1 Introduction

In this RMarkdown file, the extended methods and data-analysis for the manuscript “Multisystem inflammatory syndrome in children related to COVID-19: a systematic review” is described. The complete data-analysis can be reproduced from the data collection sheet (in .xls format), provided in the supplementary files of the manuscript or on Github.

Prior to conducting the review, the study protocol was published on the PROSPERO systematic review register (CRD42020189248).

knitr::opts_chunk$set(cache = FALSE, warning = FALSE, message = FALSE)
options(digits = 3)
library(tidyverse)
require(readxl)
require(httr)
require(reshape2)
require(broom)
require(RColorBrewer)
require(scales)
require(ggrepel)
require(gridExtra)
require(ggExtra)
library(ggbeeswarm)
require(ggpubr)
library(cowplot)
library(naniar)
require(DT)
require(zoo)
require(psych)
library(skimr)
library(UpSetR)
library(see)
library(wesanderson)
library(padr)

options(scipen=999)

co_hb <- 12
co_neutrophilia <- 8000
co_CRP <- 10
co_lympho <- 1250
co_fibrino <- 400
co_Ddim <- 250
co_ferritin <- 300
co_albu <- 34
co_PCT <- 0.49
co_LDH <- 280
co_IL6 <- 16.4
co_ESR <- 22
co_BNP <- 100
co_NTproBNP <- 400
co_tropo <- 40
co_WBC <- 11000
co_platelet <- 150000
co_sodium <- 135
#input = df_cohort_controls
#find = "max"
#param = "CRP"

collapse_labvals_cohort <- function(input, find, param, verbose = FALSE){
  if (find == "max"){
    df <- input %>% select(contains(param) | contains("cohort_id") | contains("cohort_type") | contains("tot_cases_n"))
    if (verbose == TRUE){
      print("Column extracted from cohorts:")
      print(colnames(df))
    }
    df_med <- df %>% select(contains("med"))
    df_med <- type_convert(df_med)
    df_med <- df_med %>% mutate_all(funs(replace_na(., -999)))
   # colnames(df_med)[max.col(df_med,ties.method="first")]
    df_med <- df_med %>% mutate(med = as.numeric(apply(df_med, 1, max)))
    
    df_min <- df %>% select(contains("Q1"))
    df_min <- type_convert(df_min)
    df_min <- df_min %>% mutate_all(funs(replace_na(., 0)))
    #colnames(df_min)[max.col(df_min,ties.method="first")]
    df_min <- df_min %>% mutate(min = as.numeric(apply(df_min, 1, max)))
    
    df_max <- df %>% select(contains("Q3"))
    df_max <- type_convert(df_max)
    df_max <- df_max %>% mutate_all(funs(replace_na(., 0)))
    #colnames(df_max)[max.col(df_max,ties.method="first")]
    df_max <- df_max %>% mutate(max = as.numeric(apply(df_max, 1, max)))
    
    df_full <- cbind(df %>% select(cohort_id, cohort_type, tot_cases_n), df_med %>% select(med), df_min %>% select(min), df_max %>% select(max))
    df_full[df_full == -999] <- NA
    names(df_full)[names(df_full) == 'max'] <- paste0(param, "_max")
    names(df_full)[names(df_full) == 'min'] <- paste0(param, "_min")
    names(df_full)[names(df_full) == 'med'] <- paste0(param, "_med")
    df_full$data_descr <- "IQR"
    df_full$cohort_id <- paste0(df_full$cohort_id, " (n = ", as.character(df_full$tot_cases_n),")")
    write.csv(df_full, paste0("./data/cohort_", param, ".csv"))
    print(datatable(df_full, caption = paste0("overview of ", param)))
    return(df_full)
  }
    else if (find == "min"){
    df <- input %>% select(contains(param) | contains("cohort_id") | contains("cohort_type") | contains("tot_cases_n"))
    if (verbose == TRUE){
    print("Column extracted from cohorts:")
    print(colnames(df))
    }
    df_med <- df %>% select(contains("med"))
    df_med <- type_convert(df_med)
    df_med <- df_med %>% mutate_all(funs(replace_na(., 1e6)))
   # colnames(df_med)[max.col(df_med,ties.method="first")]
    df_med <- df_med %>% mutate(med = as.numeric(apply(df_med, 1, min)))
    
    df_min <- df %>% select(contains("Q1"))
    df_min <- type_convert(df_min)
    df_min <- df_min %>% mutate_all(funs(replace_na(., 1e6)))
    #colnames(df_min)[max.col(df_min,ties.method="first")]
    df_min <- df_min %>% mutate(min = as.numeric(apply(df_min, 1, min)))
    
    df_max <- df %>% select(contains("Q3"))
    df_max <- type_convert(df_max)
    df_max <- df_max %>% mutate_all(funs(replace_na(., 1e6)))
    #colnames(df_max)[max.col(df_max,ties.method="first")]
    df_max <- df_max %>% mutate(max = as.numeric(apply(df_max, 1, min)))
    
    df_full <- cbind(df %>% select(cohort_id, cohort_type, tot_cases_n), df_med %>% select(med), df_min %>% select(min), df_max %>% select(max))
    df_full[df_full == 1e6] <- NA
    names(df_full)[names(df_full) == 'max'] <- paste0(param, "_max")
    names(df_full)[names(df_full) == 'min'] <- paste0(param, "_min")
    names(df_full)[names(df_full) == 'med'] <- paste0(param, "_med")
    df_full$data_descr <- "IQR"
    df_full$cohort_id <- paste0(df_full$cohort_id, " (n = ", as.character(df_full$tot_cases_n),")")
    write.csv(df_full, paste0("./data/cohort_", param, ".csv"))
    print(datatable(df_full, caption = paste0("overview of ", param)))
    return(df_full)
  }
}

#input = df_singlecases
#find = "max"
#param = "CRP"

collapse_labvals_single <- function(input, find, param, verbose = FALSE){
  if (find == "max"){
    df <- input %>% select(contains(param) | contains("cohort_id"))
    if (verbose == TRUE){
    print("Column extracted from single cases:")
    print(colnames(df))
    }
    df_coll <- df %>% mutate_all(funs(replace_na(., -999)))
    df_coll <- type_convert(df_coll)
   # colnames(df_med)[max.col(df_med,ties.method="first")]
    df_coll <- df_coll %>% mutate(max = as.numeric(apply(df_coll, 1, max)))
    
    df_coll[df_coll == -999] <- NA
    names(df_coll)[names(df_coll) == 'max'] <- paste0(param, "_max")
    df_coll$data_descr <- "IQR"
    df_coll$cohort_id <- paste0("single cases (n = ", as.character(n_single_cases),")")
    write.csv(skim(df_coll), paste0("./data/singlecases_", param, ".csv"))
    return(df_coll)
  }
    else if (find == "min"){
    df <- input %>% select(contains(param) | contains("cohort_id"))
    if (verbose == TRUE){
    print("Column extracted from single cases:")
    print(colnames(df))
    }
    df_coll <- df %>% mutate_all(funs(replace_na(., 1e6)))
   # colnames(df_med)[max.col(df_med,ties.method="first")]
    df_coll <- df_coll %>% mutate(min = as.numeric(apply(df_coll, 1, min)))
    
    df_coll[df_coll == 1e6] <- NA
    names(df_coll)[names(df_coll) == 'min'] <- paste0(param, "_min")
    df_coll$cohort_id <- paste0("single cases (n = ", as.character(n_single_cases),")")
    write.csv(skim(df_coll), paste0("./data/singlecases_", param, ".csv"))
    return(df_coll)
  }
}


moveme <- function (df, movecommand) {
  invec <- names(df)
  
  movecommand <- lapply(strsplit(strsplit(movecommand, ";")[[1]], 
                                 ",|\\s+"), function(x) x[x != ""])
  movelist <- lapply(movecommand, function(x) {
    Where <- x[which(x %in% c("before", "after", "first", 
                              "last")):length(x)]
    ToMove <- setdiff(x, Where)
    list(ToMove, Where)
  })
  myVec <- invec
  for (i in seq_along(movelist)) {
    temp <- setdiff(myVec, movelist[[i]][[1]])
    A <- movelist[[i]][[2]][1]
    if (A %in% c("before", "after")) {
      ba <- movelist[[i]][[2]][2]
      if (A == "before") {
        after <- match(ba, temp) - 1
      }
      else if (A == "after") {
        after <- match(ba, temp)
      }
    }
    else if (A == "first") {
      after <- 0
    }
    else if (A == "last") {
      after <- length(myVec)
    }
    myVec <- append(temp, values = movelist[[i]][[1]], after = after)
  }
  
  df[,match(myVec, names(df))]
}

makeBarplot <- function(var_id_cohort, var_id_single, var_id){

        n_cohort <- df_cohort %>% select(tot_cases_n) %>% sum()#, outcome_death_n)
        var_cohort <- df_cohort[var_id_cohort] %>% sum(., na.rm = TRUE)#, outcome_death_n)
        
        n_single <- df_singlecases %>% nrow()
        
        var_single <- df_singlecases %>% filter(get(var_id_single) == TRUE) %>% nrow()
        
        n_all <- n_cohort + n_single
        var_all <- var_cohort + var_single
        
        bar_df_abs <- data.frame(x = c("cohort", "cohort", "single cases", "single cases", "all", "all"), col = c("total", var_id, "total", var_id, "total", var_id), vals = c(n_cohort, var_cohort, n_single, var_single, n_all, var_all) )
        
        bar_df_prct <- data.frame(x = c("cohort", "cohort", "single cases", "single cases", "all", "all"), col = c(paste0(var_id, " -"), paste0(var_id, " +"), paste0(var_id, " -"), paste0(var_id, " +"), paste0(var_id, " -"), paste0(var_id, " +")), vals = c(100-(var_cohort/n_cohort*100), var_cohort/n_cohort*100, 100-(var_single/n_single*100), var_single/n_single*100, 100-(var_all/n_all*100), var_all/n_all*100) )

        
        p_abs <- ggplot(bar_df_abs, aes(x = x, y =  vals, fill = col)) +
            geom_bar(stat = "identity", position = "dodge") +
            theme_bw() + 
            labs(title = paste0("Total cases vs ", var_id), subtitle = "Absolute numbers", x = "group", y = "n", col = "") +
  scale_fill_manual(values = wes_palette("Royal1"))
        
        
        p_prct <- ggplot(bar_df_prct, aes(x = x, y =  vals, fill = col)) +
            geom_bar(stat = "identity", position = "fill") +
            theme_bw() + 
            labs(title = paste0(var_id), subtitle = "Percent", x = "group", y = "%", col = "")  +
    scale_y_continuous(labels = scales::percent)+
  scale_fill_manual(values = wes_palette("Royal1"))
        
        ggarrange(p_abs, p_prct, legend = "bottom")
  
}

makeHeatmap_cohort <- function(param1, colname_single, exclude_single = NULL, plottitle, textsize = 3){
  var_cohort <- df_cohort %>% select(("cohort_id") | "tot_cases_n" | ( contains(param1) & contains("_n")))
  var_cohort$cohort_id <- paste0(var_cohort$cohort_id, " (n = ", as.character(var_cohort$tot_cases_n),")")
  var_cohort <- var_cohort %>% 
    gather(variable, value, 3:ncol(var_cohort)) %>% group_by(cohort_id, variable) %>% summarize(prct = value/tot_cases_n*100)
  var_cohort$variable <- sub("_n", "", var_cohort$variable)

if (!is.null(exclude_single)){
  var_single <- df_singlecases %>% select(-contains(exclude_single))
  var_single <- var_single %>% select(contains(colname_single))
} else
{
  var_single <- df_singlecases %>% select(contains(colname_single))
}

 #%>% select(-contains("any"))
cols <- sapply(var_single, is.logical)
var_single[,cols] <- lapply(var_single[,cols], as.numeric)
var_single <- colSums(var_single, na.rm = TRUE)
var_single <- var_single/nrow(df_singlecases)*100
var_single <- as.data.frame(var_single) %>% rownames_to_column()
var_single$cohort_id <- paste0("single cases (n = ", n_single_cases,")")
colnames(var_single) <- c("variable", "prct", "cohort_id")


missing <- setdiff(var_single$variable, var_cohort$variable)
if (length(missing) != 0 ){
  missing_df <- data.frame(variable = missing, prct = NA, cohort_id = unique(var_cohort$cohort_id))
  var_cohort <- bind_rows(var_cohort, as_tibble(missing_df))
} else if (length(missing) == 0) {
  missing <- setdiff(var_cohort$variable, var_single$variable)
  if (length(missing) != 0){
  missing_df <- data.frame(variable = missing, prct = NA, cohort_id = unique(var_single$cohort_id))
  var_single <- bind_rows(var_single, as_tibble(missing_df))
  }
}

hm_cohort <- ggplot(var_cohort, aes(x = variable, y = cohort_id, fill = prct)) + 
    geom_tile() + theme_classic() +
    theme(axis.text.x=element_blank(), axis.ticks.x=element_blank(), axis.line=element_blank())+
   scale_fill_gradient(low = "yellow", high="red", na.value = "lightgray", limits = c(0,100)) +
    labs(x = "", y = "cohort", title =plottitle) +
    geom_text(aes(label=round(prct, 2)), size = textsize, color = "black")

hm_single <- ggplot(var_single, aes(x = variable, y = cohort_id, fill = prct)) + 
    geom_tile() +  theme_classic() +
    theme(axis.text.x=element_text(angle=90, hjust=1), axis.line=element_blank())+
    scale_fill_gradient(low = "yellow", high = "red", na.value = "lightgray", limits = c(0,100))+ labs(y = "cohort") +
    geom_text(aes(label=round(prct, 2)), size = textsize, color = "black") 

plot_grid(hm_cohort, hm_single, align = "v", nrow = 2, rel_heights = c(1/2, 1/2))
}

2 Search strategy

Electronic bibliographical databases were searched, both indexed (PubMed, Embase) and preprint repositories (BioRxiv and MedRxiv). Additionally, COVID-19-specific research repositories were be searched (Cochrane COVID‐19 Study Register, the World Health Organization (WHO) COVID‐19 Global Research Database). Publications in English language between 31 December 2019 up to 30 June 2020, when the final search was carried out, were reviewed on eligibility. Both finished and ongoing studies were considered. The reference lists of the included studies were considered as an additional source.

Search strategy focused on keywords involving the hyperinflammatory presentation (PIMS-TS, MIS-C, hyperinflammation, HLH, toxic shock syndrome, vasculitis, Kawasaki disease), as well as the association with COVID-19 (SARS-CoV-2, COVID-19, novel coronavirus) and the pediatric population (children, adolescent, pediatric). Structured hierarchic keywords (MeSH, Emtree) and wildcards were used when applicable. Boolean operators were used to combine the various keywords of interest. Below, the full search terms are presented for the different databases).

2.1 PubMed

(“PIMS*” OR “MIS*” OR “multisystem inflammat*” OR “hyperinflammat*” OR “inflammatory disease” OR “systemic inflammat*” OR “cytokine release” OR “Kawasaki*” OR “vasculitis” OR “toxic shock” OR “shock” OR ("pediatric multisystem inflammatory disease, COVID-19 related" [Supplementary Concept]) OR "Mucocutaneous Lymph Node Syndrome"[Mesh] OR "Shock"[Mesh] OR "Vasculitis"[Mesh] OR “inflammation”[MeSH]) AND (“covid*” or “sars-cov-2” or “2019-nCov” or “novel coronavirus” or “coronavirus disease” or "COVID-19" [Supplementary Concept] OR "severe acute respiratory syndrome coronavirus 2" [Supplementary Concept]) AND (“child*” or “adolescen*” or “teen*” or “pediatric*” or “infant” or “newborn” or "Child"[Mesh] OR "Adolescent"[Mesh] OR "Pediatrics"[Mesh] or "Infant, Newborn"[Mesh] or "Infant"[Mesh]) AND ("2019/12/31"[Date - Publication] : "3000"[Date - Publication])  

2.2 Embase

('pims*' OR 'mis' OR ‘mis-c’ OR 'multisystem inflammat*' OR 'hyperinflammat*' OR 'inflammatory disease' OR 'systemic inflammat*' OR 'cytokine release' OR 'kawasaki*' OR 'vasculitis' OR 'toxic shock' OR 'shock') AND ('covid*' OR 'sars-cov-2' OR '2019-ncov' OR 'novel coronavirus' OR 'coronavirus disease') AND ('child*' OR 'adolescen*' OR 'teen*' OR 'pediatric*' OR 'infant' OR 'newborn') AND [31-12-2019]/sd  

2.3 BioRxiv and MedRxiv

Literature search in biorxiv and medrxiv was done with the R by downloading the data from the dedicated COVID-19 SARS-CoV-2 preprints page in json format, and can be found on Github.

2.4 Cochrane COVID-19 study register

(pims* OR mis OR "mis-c" OR "multisystem inflammat*" OR hyperinflammat* OR "inflammatory disease" OR "systemic inflammat*" OR "cytokine release" OR kawasaki* OR vasculitis OR "toxic shock" OR shock) AND (child* OR adolescen* OR teen* OR pediatric* OR infant OR newborn) 

2.5 WHO COVID-19 Global literature on coronavirus disease

("pims*" OR "mis" OR "mis-c" OR "multisystem inflammat*" OR "hyperinflammat*" OR "inflammatory disease" OR "systemic inflammat*" OR "cytokine release" OR "kawasaki*" OR "vasculitis" OR "toxic shock" OR "shock") AND ("child*" OR "adolescen*" OR "teen*" OR "pediatric*" OR "infant" OR "newborn") 

3 Study selection and risk of bias assessment

Original studies were included with following designs: RCT, observational studies, case-control studies, cross-sectional studies, case reports and case series.

Records eligible for inclusion should present clinical cases fulfilling the following 3 criteria:

Inclusion criteria

  1. Study population: hyperinflammatory syndrome meeting the case definitions of PIMS-TS or MIS(-C) in children (0-19 years of age) with a temporal association with confirmed or probable COVID-19
  2. Outcome: clinical, epidemiological and immunological descriptions, therapeutic management and clinical effect, and prognosis of individuals or cohorts of patients.
  3. Types of study designs: RCT, observational studies, case-control studies, cross-sectional studies, case reports and case series

Exclusion criteria 1. Studies on adult patients with SARS-CoV-2 infection and/or SARS-CoV-2 associated hyperinflammatory syndromes 2. Studies on pediatric patients with other coronavirus infections (SARS-CoV-1 and Middle East Respiratory Syndrome Coronavirus (MERS-CoV) infection or other respiratory infections. 3. Studies with incomplete or lacking necessary data 4. Duplicate studies 5. Studies without accessible full text versions 6. Studies not in English language

Study selection was a two-stage process with, first, titles and abstracts of studies screened with retrieval using the search strategy and then, second, full text screening of potentially eligible studies assessed by two reviewers independently. Any disagreement over the eligibility of particular studies was resolved through discussion with a third reviewer.

The Preferred Reporting Items for Systematic Reviews and Meta-Analyses (PRISMA) checklist was used to guide the study selection and extraction process. Risk for bias on eligible observational studies were assessed by LH according to the NewCastle-Ottawa Scale (NOS), with full verification of all judgments by RVP. Level of evidence was rated according to Sackett.

4 PRISMA flow diagram

5 Data extraction

All original studies describing clinical cases meeting the case definition of PIMS-TS, as defined by RCPCH, were eligible for inclusion. Primary outcome analysis focused on clinical, epidemiological and immunological manifestations, therapeutic management and prognosis. 

The following data points were outlined to be extracted out of eligible records: patient characteristics (e.g. sex, age, ethnicity, anthropometry,…), comorbidities (e.g. cardiovascular disease, respiratory disease, diabetes mellitus, renal disease, malignancy/cancer, immunodeficiency,…), SARS-CoV-2 infection related data (e.g. close contacts with confirmed or suspected COVID-19, PCR and serology results,…), clinical symptoms (e.g. fever, respiratory, gastro-intestinal, neurological, dermatological, renal or cardiac manifestations, description of Kawasaki criteria,…), laboratory tests at various time points (e.g. haemoglobin, WBC, lymphocyte, neutrophil and platelet counts, sodium, ferritin, D-dimer, fibrinogen, albumin, creatinine, liver transaminases, CK, LDH, troponin, NT-proBNP, CRP, ESR, serum cytokines, complement, immunoglobulins,…), radiological results, hospital admission data (days of hospitalisation, days of ICU care,…), critical care interventions (invasive and non-invasive ventilation, inotropes/vasopressors use, ECMO,…) and therapeutics and their effect (corticosteroids, aspirin, IVIG, biotherapeutics, antibiotics,…). Fields with insufficient data will be excluded from final analysis. Additional parameters were included if relevant.

Cases were excluded if insufficient data suggesting a temporal association with SARS-CoV-2 was presented. A recent or current positive SARS-CoV-2 PCR (nasopharyngeal, fecal, other) or serology (IgA, IgM, IgG) results needed to be presented, or history of close contact (e.g. household) with a confirmed or highly suspect case of COVID-19 was required. Studies were excluded if data was inconsistently presented.

As a secondary outcome, it was outlined to make a qualitative assessment and propose an immunological mechanism underpinning this inflammatory syndrome based on the cases reported in literature and/or immunological investigations performed in these affected children. Nevertheless, up to the final search, insufficient data was available to conduct such assessments.

A single reviewer (LH) extracted data using a standardized form, while a second reviewer (RVP) cross checked all data for correctness and completeness. Any disagreement over study eligibility and conflict on data extraction were resolved by a third reviewer (FH).

Cohort studies and studies reporting on single cases were analysed separately, as we did not have access to the individual case characteristics of the cohort studies. For the cohort studies, proportions were calculated by summing only the studies which report on the variable, except for rare conditions such as death, comorbidities, use of ECMO or biopharmaceuticals.

6 Data import and cleaning

6.1 Single cases

After data collection, we import the single cases from the general excel sheet and transform the excel sheet so that variables are columns and rows are cases. Columns without any values are also removed.

The single cases from Pouletty (10.1136/annrheumdis-2020-217960) are excluded (as they are included in the cohorts).

6.1.1 Making summary statistics

In this section, data is summarized. For example, if there are any comorbidities present, a column “comorb_any” is added and annotated as TRUE. The same is done for COVID serology and symptoms of major organ (respiratory, cardiovascular etc).

If IgG, IgA, IgM or COVID serology is reported as positive, the column covid_sero_any is annotated as TRUE.

If PCR+, stool PCR+, IgG, IgA, IgM or COVID serology is reported as positive, the column covid_pos_any is annotated as TRUE.

If any respiratory symptoms, symp_resp_any is annotated as TRUE.

If any GI symptoms, symp_GI_any is annotated as TRUE.

If any neurological symptoms, symp_neuro_any is annotated as TRUE.

If any renal symptoms, symp_renal_any is annotated as TRUE.

If any cardiovascular symptoms, symp_cardiovasc_any is annotated as TRUE.

6.2 Cohorts

Afterwards, we do the same for the cohort sheet.

The papers by Grimaud et al. and Verdoni et al. are removed from the cohort dataframe, as most information is present in the single cases dataframe.

7 Descriptive statistics

7.1 General

Click on the any of the tabs above to see descriptive statistics for every variable

7.2 Single cases

How to read
Under “Variable type: logical”, the number of true/falses are depicted. E.g. at the top we can see that there are 95 number of rows (= 95 patients). Overweight has 79 missing values (17% is complete), which means that 95-79=16 patients have either “TRUE” or “FALSE” for overweight. Of these 16, 9 are marked as “TRUE” for overweight.

7.3 Cohorts

How to read
The sum column equals the sum of all individuals, e.g. sum(tot_cases_n) means that there are 592 patients in total in the cohorts; sum(outcome_death_n) means that 9 patients died.

The “Prct_total” column is the percentage of e.g. death (9/592). Only makes sense where n is reported e.g. therapy (not for lab values).

8 Data exploration

Important

For the cohorts, percentages describe the total (e.g. positive) cases, divided by the sum of the total cases of studies reporting the variable.

8.1 Cases in function of COVID pandemic

To investigate the relationship of the published PIMS cases with the ongoing COVID-19 pandemic, the case data from Johns Hopkins was downloaded (and added to this repository).

The list was filtered on the UK, US, Italy and France, as these country contribute the most to our dataset.

Caveat: this is a distored image of the PIMS cases: as the cases are published together, their true date of diagnosis is unknown.

firstdiff <- function(x) {
   shifted <- c(0,x[1:(length(x)-1)])
   x-shifted
   }

USA_cases <- read_csv("./data/time_series_covid19_confirmed_US.csv")
USA_cases <- USA_cases %>% select(-c(UID, iso2, iso3, code3, FIPS, Admin2, Province_State, Lat, Long_, Combined_Key))

names(USA_cases)[names(USA_cases) == 'Country_Region'] <- "Country/Region"

global_cases <- read_csv("./data/time_series_covid19_confirmed_global.csv")
global_cases <- global_cases %>% select(-c(`Province/State`, Lat, Long))

global_cases <- rbind(USA_cases, global_cases)

global_cases <- global_cases %>% melt()
global_cases$variable <- as.Date(global_cases$variable, format = "%m/%d/%y")
colnames(global_cases) <- c("country", "date_of_publication", "tot_cases_covid")
global_cases <- global_cases %>% filter(country == "United Kingdom"  | country == "Italy" | country == "France" | country == "US")
all_glob_cases <- global_cases %>% group_by(date_of_publication) %>% summarise(total_cases = sum(tot_cases_covid))
all_glob_cases$newcases <- firstdiff(all_glob_cases$total_cases)
all_glob_cases$newcase_roll7 <- zoo::rollmean(all_glob_cases$newcases, k = 7, fill = NA)

evo_cases <- rbind(df_cohort %>% select(tot_cases_n, date_of_publication) %>% mutate(type = "cohort"), 
df_singlecases %>% select(date_of_publication) %>% mutate(tot_cases_n = 1, type = "single"))

evo_cases <- pad(evo_cases)
evo_cases$tot_cases_n[is.na(evo_cases$tot_cases_n)] <- 0
evo_cases$cumplot <- cumsum(evo_cases$tot_cases_n)

full_data <- merge(evo_cases, all_glob_cases, all = TRUE)

p1 <- ggplot(full_data , aes(x = date_of_publication, y = cumplot)) +
        geom_col(position = "dodge", col = wes_palette("Royal1")[2], fill = wes_palette("Royal1")[2]) + 
        theme_bw() + geom_line(aes(x = date_of_publication, y = newcase_roll7/175)) +
        labs(x = "Date", y = "cumulative number of cases", title = "Number of published cases") +  scale_x_date(limits = as.Date(c('2020-01-15','2020-07-01'))) + scale_y_continuous(
    "cumulative number of published cases", 
    sec.axis = sec_axis(~ . * 175, name = "new COVID-19 cases (7-day average)")
  )

p1 

ggsave(p1, filename = "./plots/covid_evo_total.png", dpi = 300, height=7, width=10)
ggsave(p1, filename = "./plots/covid_evo_total.svg", dpi = 300, height=7, width=10)
ggsave(p1, filename = "./plots/covid_evo_total.pdf", dpi = 300, height=7, width=10)



all_glob_cases <- global_cases %>% group_by(date_of_publication, country) %>% summarise(total_cases = sum(tot_cases_covid)) %>% ungroup()


all_glob_cases <- all_glob_cases %>% group_by(country) %>%
  mutate(newcases = firstdiff(total_cases)) %>% ungroup()

#all_glob_cases$newcases <- firstdiff(all_glob_cases$total_cases)
all_glob_cases <- all_glob_cases %>% group_by(country)  %>% mutate(newcase_roll7 = zoo::rollmean(newcases, k = 7, fill = NA)) 

evo_cases <- rbind(df_cohort %>% select(tot_cases_n, date_of_publication, country) %>% mutate(type = "cohort"), 
df_singlecases %>% select(date_of_publication, country) %>% mutate(tot_cases_n = 1, type = "single"))

country_barplot <- evo_cases

evo_cases <- pad(evo_cases)
#evo_cases$tot_cases_n[is.na(evo_cases$tot_cases_n)] <- 0
#evo_cases$tot_cases_n[is.na(evo_cases$tot_cases_n)] <- 0
evo_cases <- evo_cases %>% group_by(country) %>% mutate(cumplot = cumsum(tot_cases_n)) %>% ungroup()
evo_cases <- evo_cases %>% fill(country)


full_data <- merge(evo_cases, all_glob_cases, all = TRUE)
full_data_filt <- full_data %>% filter(country == "United Kingdom"  | country == "Italy" | country == "France" | country == "US")

full_data_filt <- full_data_filt %>% mutate(continent = ifelse(country == "US", "US", "Europe"))

p1 <- ggplot(full_data_filt , aes(x = date_of_publication, y = cumplot)) +
        geom_col(position = "dodge", aes(fill = country, col = country)) + 
        theme_bw() + 
        scale_color_manual(values = wes_palette("Darjeeling2")[c(1,3,4,2)]) +
  scale_fill_manual(values = wes_palette("Darjeeling2")[c(1,3,4,2)]) +
        geom_line(aes(x = date_of_publication, y = newcase_roll7/100, col = country)) +
        labs(x = "Date", y = "cumulative number of cases (bars)", title = "Number of published cases, per country") +
        scale_x_date(limits = as.Date(c('2020-03-01','2020-07-01'))) + scale_y_continuous(    "cumulative number of published cases (bars)", 
    sec.axis = sec_axis(~ . * 100, name = "new COVID-19 cases (7-day average, lines)") 
  ) + 
      theme(legend.position="bottom") + 
      facet_wrap(~continent, scales = "free_y")

p1

8.4 Sex

n_cohort <- df_cohort %>% select(tot_cases_n) %>% sum()
var_cohort <- df_cohort %>% select(contains("sex"))
var_cohort <- colSums(var_cohort, na.rm = TRUE)
var_cohort <- var_cohort/sum(df_cohort$tot_cases_n)*100
var_cohort["sex_na"] <- (100 - var_cohort["sex_m"] - var_cohort["sex_f"])

var_control <- df_cohort_controls %>% filter(cohort_id == "Pouletty - control") %>% select(contains("sex"))
var_control <- colSums(var_control, na.rm = TRUE)
var_control <- var_control/sum(df_cohort_controls %>% filter(cohort_id == "Pouletty - control") %>% select(tot_cases_n))*100
var_control["sex_na"] <- (100 - var_control["sex_m"] - var_control["sex_f"])

n_single <- df_singlecases %>% nrow()
var_single <- df_singlecases %>% select(contains("sex"))
var_single$sex_m <- ifelse(var_single$sex == "M", TRUE, FALSE)
var_single$sex_f <- ifelse(var_single$sex == "F", TRUE, FALSE)
cols <- sapply(var_single, is.logical)
var_single[,cols] <- lapply(var_single[,cols], as.numeric)
var_single <- colSums(var_single %>% select(-sex), na.rm = TRUE)
var_single <- var_single/nrow(df_singlecases)*100
var_single["sex_na"] <- (100 - var_single["sex_m"] - var_single["sex_f"])

bar_df_prct <- data.frame(
  x = c("males", "females", "missing", "males", "females", "missing", "males", "females", "missing"),
  vals = c(var_single, var_cohort, var_control),
  col = c(rep("single", length(var_single)), rep("cohorts", length(var_cohort)), rep("histor ctrl", length(var_control))
))

p_prct <- ggplot(bar_df_prct, aes(x = col, y =  vals, fill = x)) +
    geom_bar(stat = "identity", position = "stack") +
    theme_bw() + 
    labs(title = "Male/female distribution in dataset", subtitle = "Prct", x = "sex", y = "%", col = " ")  + lims(y = c(0,100)) + theme(axis.text.x=element_text(angle=90, hjust=1))+
  scale_fill_manual(values = wes_palette("Royal1"))
p_prct

var_cohort <- df_cohort %>% select(contains("sex") | ("cohort_id") | "tot_cases_n")
sex_f <- var_cohort %>% group_by(cohort_id) %>% summarize(prct = sex_f/tot_cases_n) %>%  mutate(sex = "female")
sex_m <- var_cohort %>% group_by(cohort_id) %>% summarize(prct = sex_m/tot_cases_n) %>% mutate(sex = "male")
sex_all <- rbind(sex_f, sex_m)

p_sex_cohort <- ggplot(sex_all, aes(y = cohort_id, x = prct, fill = sex)) + 
          geom_bar(stat = "identity", position = "fill") + 
          theme_bw() + labs(x = "") + 
          scale_fill_manual(values = wes_palette("Royal1"))

var_controls <- df_cohort_controls %>% filter(cohort_id == "Pouletty - control") %>% select(contains("sex") | ("cohort_id") | "tot_cases_n")
sex_f <- var_controls %>% group_by(cohort_id) %>% summarize(prct = sex_f/tot_cases_n) %>% mutate(sex = "female")
sex_m <- var_controls %>% group_by(cohort_id) %>% summarize(prct = sex_m/tot_cases_n) %>% mutate(sex = "male")
sex_all <- rbind(sex_f, sex_m)

p_sex_controls <- ggplot(sex_all, aes(y = cohort_id, x = prct, fill = sex)) + 
          geom_bar(stat = "identity", position = "fill") + 
          theme_bw() + labs(x = "") + 
          scale_fill_manual(values = wes_palette("Royal1"))

n_single <- df_singlecases %>% nrow()
var_single <- df_singlecases %>% select(contains("sex"))
var_single$sex_m <- ifelse(var_single$sex == "M", TRUE, FALSE)
var_single$sex_f <- ifelse(var_single$sex == "F", TRUE, FALSE)
cols <- sapply(var_single, is.logical)
var_single[,cols] <- lapply(var_single[,cols], as.numeric)
var_single <- colSums(var_single %>% select(-sex), na.rm = TRUE)
var_single <- var_single/nrow(df_singlecases)*100

sex_single <- data.frame(cohort_id = "single_cases", prct = c(var_single["sex_m"], var_single["sex_f"]), sex = c("male", "female"))

p_sex_single <- ggplot(sex_single, aes(y = cohort_id, x = prct, fill = sex)) + 
          geom_bar(stat = "identity", position = "fill") + 
          theme_bw() + 
          scale_fill_manual(values = wes_palette("Royal1"))

a <- plot_grid(p_sex_cohort, p_sex_controls, p_sex_single, align = "v", nrow = 3, rel_heights = c(5/7, 1/7, 1/7))
a

8.5 Age distribution

cohort_age <- df_cohort_controls %>% select(contains("cohort_id") | contains("age") | contains("cohort_type")  | contains("tot_cases_n"))
cohort_age$cohort_id <- paste0(cohort_age$cohort_id, " (n = ", cohort_age$tot_cases_n,")")
cohort_age$age_med_yrs <- as.numeric(cohort_age$age_med_yrs )
cohort_age$age_Q1_yrs <- as.numeric(cohort_age$age_Q1_yrs)
cohort_age$age_Q3_yrs <- as.numeric(cohort_age$age_Q3_yrs)
cohort_age$age_min_yrs <- as.numeric(cohort_age$age_min_yrs)
cohort_age$age_max_yrs <- as.numeric(cohort_age$age_max_yrs)

cohort_age$data_descr <- ifelse(!is.na(cohort_age$age_Q1_yrs) & is.na(cohort_age$age_min_yrs) , "IQR", 
                                ifelse(is.na(cohort_age$age_Q1_yrs) & !is.na(cohort_age$age_min_yrs), "range", 
                                    ifelse(!is.na(cohort_age$age_Q1_yrs) & !is.na(cohort_age$age_min_yrs), "both", "none")))

p_age_cohort <- ggplot(cohort_age %>% filter(cohort_type == "covid"), aes(y = cohort_id, x = age_med_yrs, col = data_descr)) + 
        geom_point(size = 4) + 
        geom_errorbar(aes(xmin=age_Q1_yrs, xmax=age_Q3_yrs), width=.8, position=position_dodge(.9)) +
        geom_errorbar(aes(xmin=age_min_yrs,  xmax=age_max_yrs), width=.2, position=position_dodge(.9)) +
        theme_bw() + lims(x = c(0,21)) + 
        labs(y = "cohort", x = "", col = "bars") + theme(legend.position="top")+
        scale_color_manual(values = c(wes_palette("BottleRocket2")[1:3], wes_palette("BottleRocket1")[2]))

p_age_controls <- ggplot(cohort_age %>% filter(cohort_type != "covid"), aes(y = cohort_id, x = age_med_yrs, col = data_descr)) + 
        geom_point(size = 4) + 
        geom_errorbar(aes(xmin=age_Q1_yrs, xmax=age_Q3_yrs), width=.2, position=position_dodge(.9)) +
        geom_errorbar(aes(xmin=age_min_yrs,  xmax=age_max_yrs), width=.2, position=position_dodge(.9)) +
        theme_bw() + lims(x = c(0,21)) +
        labs(y = "cohort", x = "", col = "bars") + theme(legend.position="none")+
        scale_color_manual(values = wes_palette("BottleRocket2")[2])

p_age_single <- ggplot(df_singlecases, aes(x = as.numeric(age), y = paste0("single cases (n = ", n_single,")"))) +
      geom_violin(fill = wes_palette("Darjeeling2")[4]) + 
      geom_boxplot(width=.3, fill = wes_palette("Darjeeling2")[1]) + 
      theme_bw() + geom_beeswarm(groupOnX=FALSE, alpha = 0.5) + lims(x = c(0,21)) + 
      labs(y = "cohort", x = "Age (years)")

a <- plot_grid(p_age_cohort, p_age_controls, p_age_single, align = "v", nrow = 3, rel_heights = c(2/3, 1/5, 1/3))
a

8.6 Symptoms

8.6.2 Single cases + cohort

8.6.2.1 Respiratory

barSymp <- function(colname_chort, colname_single, exclude_single = NULL, plottitle){

var_cohort <- df_cohort %>% 
                        select(contains("cohort_id") | contains("tot_cases_n") | (contains(colname_chort) & contains("_n")))

var_cohort <- var_cohort %>% 
        gather(variable, value, 3:ncol(var_cohort)) %>% 
        drop_na(value)  %>% group_by(variable) %>% 
        summarize(prct = sum(value)/sum(tot_cases_n)*100)

var_cohort <- setNames(var_cohort$prct, var_cohort$variable)
names(var_cohort) <- sub("_n", "", names(var_cohort))

n_single <- df_singlecases %>% nrow()

if (!is.null(exclude_single)){
  var_single <- df_singlecases %>% select(-contains(exclude_single))
  var_single <- var_single %>% select(contains(colname_single))
} else
{
  var_single <- df_singlecases %>% select(contains(colname_single))
}

 #%>% select(-contains("any"))
cols <- sapply(var_single, is.logical)
var_single[,cols] <- lapply(var_single[,cols], as.numeric)
var_single <- colSums(var_single, na.rm = TRUE)
var_single <- var_single/nrow(df_singlecases)*100

bar_df_prct <- data.frame(
  x = c(names(var_single), names(var_cohort)),
  vals = c(var_single, var_cohort),
  col = c(rep("single", length(var_single)), rep("cohorts", length(var_cohort)))
)

p_prct <- ggplot(bar_df_prct, aes(x = x, y =  vals, fill = col)) +
    geom_bar(stat = "identity", position = "dodge") +
    theme_bw() + 
    labs(title = plottitle, 
          subtitle = "Percent of group", x = "treatment", y = "%", col = " ")  + 
          theme(axis.text.x=element_text(angle=90, hjust=1))+
          scale_fill_manual(values = wes_palette("Royal1"))
p_prct
}

makeHeatmap_cohort("symp_resp", "symp_resp", plottitle = "Cases with respiratory symptoms, per cohort")

8.7 COVID contact

var_cohort <- df_cohort %>% select(("cohort_id" | "tot_cases_n") | ( contains("covid") & contains("_n") & (contains("pos") | contains("closecont")  | contains("any"))))
var_cohort$cohort_id <- paste0(var_cohort$cohort_id, " (n = ", as.character(var_cohort$tot_cases_n),")")

var_cohort <- var_cohort %>% 
  gather(variable, value, 3:ncol(var_cohort)) %>% group_by(cohort_id, variable) %>% summarize(prct = value/tot_cases_n*100)

var_cohort$variable <- sub("n_", "", var_cohort$variable)

var_single <- df_singlecases %>% select(contains("covid"))
cols <- sapply(var_single, is.logical)
var_single[,cols] <- lapply(var_single[,cols], as.numeric)
var_single <- colSums(var_single, na.rm = TRUE)
var_single <- var_single/nrow(df_singlecases)*100
var_single <- as.data.frame(var_single) %>% rownames_to_column()
var_single$cohort_id <- paste0("single cases (n = ", n_single_cases,")")
colnames(var_single) <- c("variable", "prct", "cohort_id")


missing <- setdiff(var_single$variable, var_cohort$variable)
if (length(missing) != 0 ){
  missing_df <- data.frame(variable = missing, prct = rep(NA, length(missing)), cohort_id = rep(unique(var_cohort$cohort_id), length(missing)))
  var_cohort <- bind_rows(var_cohort, as_tibble(missing_df))
} 

missing <- setdiff(var_cohort$variable, var_single$variable)

if (length(missing) != 0) {
  if (length(missing) != 0){
data.frame(variable = missing, prct = rep(NA, length(missing)), cohort_id = rep(unique(var_single$cohort_id), length(missing)))
  var_single <- bind_rows(var_single, as_tibble(missing_df))
  }
}


hm_cohort <- ggplot(var_cohort, aes(x = variable, y = cohort_id, fill = prct)) + 
    geom_tile() + theme_classic() +
    theme(axis.text.x=element_blank(), axis.ticks.x=element_blank(), axis.line=element_blank())+
   scale_fill_gradient(low = "yellow", high="red", na.value = "lightgray", limits = c(0,100)) +
    labs(x = "", y = "cohort", title = "COVID symptoms, per cohort") +
    geom_text(aes(label=round(prct, 2)), size = 3, color = "black")

hm_single <- ggplot(var_single, aes(x = variable, y = cohort_id, fill = prct)) + 
    geom_tile() +  theme_classic() +
    theme(axis.text.x=element_text(angle=90, hjust=1), axis.line=element_blank())+
    scale_fill_gradient(low = "yellow", high = "red", na.value = "lightgray", limits = c(0,100))+ labs(y = "cohort") +
    geom_text(aes(label=round(prct, 2)), size = 3, color = "black") 

plot_grid(hm_cohort, hm_single, align = "v", nrow = 2, rel_heights = c(1/2, 1/2))

## [1] "Cases with neither PCR nor serology: 13"
## [1] "Cases with neither PCR nor serology nor closecontact: 9"

8.10 Lab values

For lab values, sometimes multiple values are reported (baseline, peak or not-specified). All lab values are collapsed based on the max (or the min for e.g. hemoglobin): so only the highest value of median, Q1 or Q3 is used. Dashed vertical line corresponds to the cutoff used in the study.

9 Case definitions

9.1 Lab reference values

Cut-offs in this study:

  • Neutrophilia > 8000/µL
  • Elevated CRP > 10 mg/L
  • Lymphopenia < 1250/µL
  • WBC > 11000/µL
  • Fibrinogen > 400 mg/dL
  • D-dimers > 250 ng/mL
  • Ferritin > 300 ng/mL
  • Albumin < 34 g/L
  • Procalcitonin > 0.49 ng/mL
  • LDH > 280 U/L
  • IL6 > 16.4 pg/mL
  • ESR > 22 mm/
  • BNP > 100 pg/mL
  • NTproBNP > 400 pg/mL
  • Troponin > 0.04 ng/mL

9.2 RCPCH, CDC and WHO

9.2.1 PIMS-TS

Source RCPCH

  1. A child presenting with persistent fever, inflammation (neutrophilia, elevated CRP and lymphopaenia) and evidence of single or multi-organ dysfunction (shock, cardiac, respiratory, renal, gastrointestinal or neurological disorder) with additional features (see listed in Appendix 1 ). This may include children fulfilling full or partial criteria for Kawasaki disease.
  2. Exclusion of any other microbial cause, including bacterial sepsis, staphylococcal or streptococcal shock syndromes, infections associated with myocarditis such as enterovirus (waiting for results of these investigations should not delay seeking expert advice).
  3. SARS-CoV-2 PCR testing may be positive or negative

We are unable to evaluate criteria 2.

PIMS_TS_fulfilled <- apply(df_singlecases, 1, function(row) {
    # persistent fever, inflammation (neutrophilia, elevated CRP and lymphopaenia) 
    pat_id <- row["patientID_int"]
    fever <- row["symp_fever"] == TRUE
    neutrophilia <- as.numeric(row["lab_neutrophils"]) > co_neutrophilia
    elevated_CRP <- (as.numeric(row["lab_CRP_admis"]) > co_CRP | as.numeric(row["lab_CRP_NS"]) > co_CRP | as.numeric(row["lab_CRP_peak"]) > co_CRP )
    lymphopenia <- as.numeric(row["lab_lymphocytes_lowest"]) < co_lympho
    inflamm <- any(fever, neutrophilia, elevated_CRP, lymphopenia)
    
    # lab values
    #fibrinogen <- row["lab_fibrino"] > co_fibrino
    #Ddimers <- row["lab_Ddim_peak"] > co_Ddim |  row["lab_Ddim_NS"] > co_Ddim
    #ferritin <- (row["lab_ferritin_NS"] > co_ferritin | row["lab_ferritin_admis"] > co_ferritin | row["lab_ferritin_peak"] > co_ferritin)
    #albumin <- row["lab_albumin_admis"] < co_albu | row["lab_albumin_lowest"] < co_albu | row["lab_albumin_NS"] < co_albu
    #lab_vals <- any(fibrinogen, Ddimers, ferritin, albumin)
    
    # single or multi-organ dysfunction (shock, cardiac, respiratory, renal, gastrointestinal or neurological disorder)
    pneumonia <- row["symp_resp_pneumonia"] == TRUE
    resp_failure <- row["symp_resp_failure"] == TRUE
    resp <- any(pneumonia, resp_failure)
    
    AKI <- row["symp_renal_AKI"] == TRUE
    RRT <- row["critcare_RRT"] == TRUE
    renal <- any(AKI, RRT)
    
    myocarditis <- row["symp_cardiovasc_myocard"] == TRUE
    pericarditis <- row["symp_cardiovasc_pericard"] == TRUE
    LVEF_under30 <- row["symp_cardiovasc_LV_less30"] == TRUE
    LVEF_30to55 <- row["symp_cardiovasc_LV_30to55"] == TRUE
    BNP <- (as.numeric(row["lab_BNP_admis"]) > co_BNP | as.numeric(row["lab_BNP_max"]) > co_BNP ) 
    NTproBNP <- as.numeric(row["lab_NTproBNP"]) > co_NTproBNP
    tropo <- as.numeric(row["lab_troponin_admis"]) > co_tropo
    shock <- row["symp_cardiovasc_shock"] == TRUE
    
    cardiovasc <- any(myocarditis, LVEF_under30, LVEF_30to55, NTproBNP, BNP, tropo, shock)
    
    rash <- row["kawasaki_exanthema"] == TRUE
    dermato <- any(rash)
    
    organ_dysfunc <- sum(resp, renal, cardiovasc, dermato, na.rm = TRUE) >= 1

    criteria_fulfilled <- (inflamm) & organ_dysfunc #&lab_vals
    #return(c(pat_id, "criteria1_inflamm" = inflamm, "criteria2_labvals" = lab_vals, "criteria3_organdysfunc" = organ_dysfunc, "criteria_fulfilled" = criteria_fulfilled))
    return(c(pat_id, "criteria1_inflamm" = inflamm, "criteria2_organdysfunc" = organ_dysfunc, "criteria_fulfilled" = criteria_fulfilled))
})

PIMS_TS_fulfilled <- PIMS_TS_fulfilled %>% t() %>% as_tibble()
PIMS_TS_fulfilled <- type_convert(PIMS_TS_fulfilled)
PIMS_TS_fulfilled_heatmap <- PIMS_TS_fulfilled
cols <- sapply(PIMS_TS_fulfilled_heatmap, is.logical)
PIMS_TS_fulfilled_heatmap[,cols] <- lapply(PIMS_TS_fulfilled_heatmap[,cols], as.numeric)
PIMS_TS_fulfilled_heatmap_melt <- PIMS_TS_fulfilled_heatmap %>% melt()
PIMS_TS_fulfilled_heatmap_melt[is.na(PIMS_TS_fulfilled_heatmap_melt)] <- 2

skim(PIMS_TS_fulfilled)
Data summary
Name PIMS_TS_fulfilled
Number of rows 95
Number of columns 4
_______________________
Column type frequency:
character 1
logical 3
________________________
Group variables None

Variable type: character

skim_variable n_missing complete_rate min max empty n_unique whitespace
patientID_int 0 1 9 10 0 95 0

Variable type: logical

skim_variable n_missing complete_rate mean count
criteria1_inflamm 0 1 1 TRU: 95
criteria2_organdysfunc 0 1 1 TRU: 95
criteria_fulfilled 0 1 1 TRU: 95

9.2.2 CDC MIS-C

Source CDC and UpToDate The case definition for MIS-C is:

  1. Age <21 years
  2. Clinical presentation consistent with MIS-C, including all of the following:
    • Fever
      • Documented fever >38.0°C (100.4°F) for ≥24 hours or
      • Report of subjective fever lasting ≥24 hours
    • Laboratory evidence of inflammation
    • Severe illness requiring hospitalization
    • Multisystem involvement
      • 2 or more organ systems involved
        • Cardiovascular (eg, shock, elevated troponin, elevated BNP, abnormal echocardiogram, arrhythmia)
        • Respiratory (eg, pneumonia, ARDS, pulmonary embolism)
        • Renal (eg, AKI, renal failure)
        • Neurologic (eg, seizure, stroke, aseptic meningitis)
        • Hematologic (eg, coagulopathy)
        • Gastrointestinal (eg, elevated liver enzymes, diarrhea, ileus, gastrointestinal bleeding)
        • Dermatologic (eg, erythroderma, mucositis, other rash)
  3. No alternative plausible diagnoses
  4. Recent or current SARS-CoV-2 infection or exposure
    • Any of the following:
    • Positive SARS-CoV-2 RT-PCR
    • Positive serology
    • Positive antigen test
    • COVID-19 exposure within the 4 weeks prior to the onset of symptoms
CDC_fulfilled <- apply(df_singlecases, 1, function(row) {
    # criteria 1
    criteria1 = TRUE
    
    # criteria 2
    pat_id <- row["patientID_int"]
    
    # fever?
    fever <- row["symp_fever"] == TRUE | row["kawasaki_fever"] == TRUE

    inflamm <- any(fever)
    
    # lab values evidence for inflammation
    neutrophilia <- as.numeric(row["lab_neutrophils"]) > co_neutrophilia
    elevated_CRP <- (as.numeric(row["lab_CRP_admis"]) > co_CRP | as.numeric(row["lab_CRP_NS"]) > co_CRP | as.numeric(row["lab_CRP_peak"]) > co_CRP )
    lymphopenia <- as.numeric(row["lab_lymphocytes_lowest"]) < co_lympho
    fibrinogen <- as.numeric(row["lab_fibrino"]) > co_fibrino
    Ddimers <- as.numeric(row["lab_Ddim_peak"]) > co_Ddim |  as.numeric(row["lab_Ddim_NS"]) > co_Ddim
    ferritin <- (as.numeric(row["lab_ferritin_NS"]) > co_ferritin | as.numeric(row["lab_ferritin_admis"]) > co_ferritin | as.numeric(row["lab_ferritin_peak"]) > co_ferritin)
    albumin <- as.numeric(row["lab_albumin_admis"]) < co_albu | as.numeric(row["lab_albumin_lowest"]) < co_albu | as.numeric(row["lab_albumin_NS"]) < co_albu
    PCT <- as.numeric(row["lab_PCT_admis"]) > co_PCT | as.numeric(row["lab_PCT_peak"]) > co_PCT | as.numeric(row["lab_PCT_NS"]) > co_PCT 
    LDH <- as.numeric(row["lab_LDH"]) > co_LDH
    IL6 <- as.numeric(row["lab_IL6"]) > co_IL6
    ESR <- as.numeric(row["lab_ESR"]) > co_ESR

    lab_vals <- any(neutrophilia, elevated_CRP, lymphopenia, fibrinogen, Ddimers, ferritin, albumin, PCT, LDH, IL6, ESR)
    
    # Ilness requiring hospitalisation
    ## used surrogate parameters for hosp
    hosp_ICU <- row["admis_hosp_days"] > 1 | row["admis_ICU_days"] > 1 | row["admis_PICU_admis"] == TRUE
    NIV <- row["critcare_NIV"] == TRUE | row["critcare_NIV_days"] > 1
    MV <- row["critcare_MV"] == TRUE | row["critcare_MV_days"] > 1
    inotrop <- row["critcare_inotrop"] == TRUE | row["critcare_inotrop_days"] > 1
    ECMO <- row["critcare_ECMO"] == TRUE 
    IVIg <- row["rx_IVIg_once"] == TRUE  |  row["rx_IVIg_multip"] == TRUE 
    biologicals <- row["rx_anakinra"] == TRUE | row["rx_tocilizumab"] == TRUE | row["rx_infliximab"] == TRUE | row["rx_antibiotics"] == TRUE | row["rx_plasma"] == TRUE | row["rx_remdesivir"] == TRUE 
    heparin <- row["rx_heparin"] == TRUE

    req_hosp <- any(hosp_ICU, NIV, MV, inotrop, ECMO, IVIg, biologicals, heparin)
    
    ## multisystem involvement >= 2
    ## respiratory
    pneumonia <- row["symp_resp_pneumonia"] == TRUE
    resp_failure <- row["symp_resp_failure"] == TRUE
    resp <- any(pneumonia, resp_failure)
    
    AKI <- row["symp_renal_AKI"] == TRUE
    RRT <- row["critcare_RRT"] == TRUE
    renal <- any(AKI, RRT)
    
    myocarditis <- row["symp_cardiovasc_myocard"] == TRUE
    pericarditis <- row["symp_cardiovasc_pericard"] == TRUE
    LVEF_under30 <- row["symp_cardiovasc_LV_less30"] == TRUE
    LVEF_30to55 <- row["symp_cardiovasc_LV_30to55"] == TRUE
    BNP <- (as.numeric(row["lab_BNP_admis"]) > co_BNP | as.numeric(row["lab_BNP_max"]) > co_BNP ) 
    NTproBNP <- as.numeric(row["lab_NTproBNP"]) > co_NTproBNP
    tropo <- as.numeric(row["lab_troponin_admis"]) > co_tropo
    shock <- row["symp_cardiovasc_shock"] == TRUE
    
    cardiovasc <- any(myocarditis, LVEF_under30, LVEF_30to55, NTproBNP, BNP, tropo, shock)
    
    rash <- row["kawasaki_exanthema"] == TRUE
    dermato <- any(rash)
    
    organ_dysfunc <- sum(resp, renal, cardiovasc, dermato, na.rm = TRUE) >= 2
    
    criteria2 <- sum(inflamm, lab_vals, req_hosp, organ_dysfunc, na.rm = TRUE) == 4
    # criteria 3
    ## not evaluable
    criteria3 = TRUE
    # criteria 4
    # COVID pos?
    PCR_pos <- row["covid_PCR_pos"] == TRUE
    stool_pos <- row["covid_PCR_stool_pos"] == TRUE
    closecontact <- row["covid_closecontact"] == TRUE
    IgA <- row["covid_IgA_pos"] == TRUE
    IgM <- row["covid_IgM_pos"] == TRUE    
    IgG <- row["covid_IgG_pos"] == TRUE    
    any_sero <- row["covid_sero_pos"] == TRUE
    
    criteria4 <- any(PCR_pos, stool_pos, closecontact, IgA, IgM, IgG, any_sero)
    
    if (FALSE %in% c(criteria1, criteria2, criteria3, criteria4)){
      criteria_fulfilled <- FALSE
    } else if (NA %in% c(criteria1, criteria2, criteria3, criteria4)){
      criteria_fulfilled <- NA
    } else if (sum(criteria1, criteria2, criteria3, criteria4, na.rm = TRUE) == 4){
      criteria_fulfilled <- TRUE
    }
    
    #criteria_fulfilled <- sum(criteria1, criteria2, criteria3, criteria4, na.rm = TRUE) == 4
    return(c(pat_id, "criteria1_age" = criteria1, "criteria2_clinical" = criteria2, "criteria3_noAlt" = criteria3, "criteria4_recentExposure" = criteria4, "criteria_fulfilled" = criteria_fulfilled))
})

CDC_fulfilled <- CDC_fulfilled %>% t() %>% as_tibble()
CDC_fulfilled <- type_convert(CDC_fulfilled)
CDC_fulfilled_heatmap <- CDC_fulfilled
cols <- sapply(CDC_fulfilled_heatmap, is.logical)
CDC_fulfilled_heatmap[,cols] <- lapply(CDC_fulfilled_heatmap[,cols], as.numeric)
CDC_fulfilled_heatmap_melt <- CDC_fulfilled_heatmap %>% melt()
CDC_fulfilled_heatmap_melt[is.na(CDC_fulfilled_heatmap_melt)] <- 2

skim(CDC_fulfilled)
Data summary
Name CDC_fulfilled
Number of rows 95
Number of columns 6
_______________________
Column type frequency:
character 1
logical 5
________________________
Group variables None

Variable type: character

skim_variable n_missing complete_rate min max empty n_unique whitespace
patientID_int 0 1 9 10 0 95 0

Variable type: logical

skim_variable n_missing complete_rate mean count
criteria1_age 0 1.00 1.00 TRU: 95
criteria2_clinical 0 1.00 0.69 TRU: 66, FAL: 29
criteria3_noAlt 0 1.00 1.00 TRU: 95
criteria4_recentExposure 9 0.91 1.00 TRU: 86
criteria_fulfilled 7 0.93 0.67 TRU: 59, FAL: 29

9.2.3 WHO case definition

Source UpToDate:

All 6 criteria must be met:

  1. Age 0 to 19 years
  2. Fever for ≥3 days
  3. Clinical signs of multisystem involvement (at least 2 of the following):
    • Rash, bilateral nonpurulent conjunctivitis, or mucocutaneous inflammation signs (oral, hands, or feet)
    • Hypotension or shock
    • Cardiac dysfunction, pericarditis, valvulitis, or coronary abnormalities (including echocardiographic findings or elevated troponin/BNP)
    • Evidence of coagulopathy (prolonged PT or PTT; elevated D-dimer)
    • Acute gastrointestinal symptoms (diarrhea, vomiting, or abdominal pain)
  4. Elevated markers of inflammation (eg, ESR, CRP, or procalcitonin)
  5. No other obvious microbial cause of inflammation, including bacterial sepsis and staphylococcal/streptococcal toxic shock syndromes
  6. Evidence of SARS-CoV-2 infection
    • Any of the following:
    • Positive SARS-CoV-2 RT-PCR
    • Positive serology
    • Positive antigen test
    • Contact with an individual with COVID-19
#row <- df_singlecases[87, ]
WHO_fulfilled <- apply(df_singlecases, 1, function(row) {
    pat_id <- row["patientID_int"]
    
    # criteria 1
    criteria1 = TRUE
    
    # criteria 2: fever?
    fever <- row["symp_fever"] == TRUE | row["kawasaki_fever"] == TRUE

    criteria2 <- any(fever)
    
    # criteria 3: clinical signs of multisystem involvement (at least 2)
    ## Rash, bilateral nonpurulent conjunctivitis, or mucocutaneous inflammation signs (oral, hands, or feet)
    rash <- row["kawasaki_exanthema"] == TRUE
    conjunctivitis <- row["kawasaki_conjunctivitis"] == TRUE
    mucocutaneaous <- row["kawasaki_mouth"] == TRUE | row["kawasaki_extremity"] == TRUE
    
    criteria3_a <- any(rash, conjunctivitis, mucocutaneaous)
    
    ## hypotension or shock
    shock <- row["symp_cardiovasc_shock"] == TRUE
    criteria3_b <- any(shock)
    
    ## cardiac dysfunction
    myocarditis <- row["symp_cardiovasc_myocard"] == TRUE
    pericarditis <- row["symp_cardiovasc_pericard"] == TRUE
    LVEF_under30 <- row["symp_cardiovasc_LV_less30"] == TRUE
    LVEF_30to55 <- row["symp_cardiovasc_LV_30to55"] == TRUE
    BNP <- (as.numeric(row["lab_BNP_admis"]) > co_BNP | as.numeric(row["lab_BNP_max"]) > co_BNP ) 
    NTproBNP <- as.numeric(row["lab_NTproBNP"]) > co_NTproBNP
    tropo <- as.numeric(row["lab_troponin_admis"]) > co_tropo
    coronary <- row["symp_cardiovasc_cordilat"] == TRUE | row["symp_cardiovasc_aneurysm"] == TRUE
    
    criteria3_c <- any(myocarditis, LVEF_under30, LVEF_30to55, NTproBNP, BNP, tropo, coronary)
    
    ## coagulopathy
    fibrinogen <- as.numeric(row["lab_fibrino"]) > co_fibrino
    Ddimers <- as.numeric(row["lab_Ddim_peak"]) > co_Ddim |  as.numeric(row["lab_Ddim_NS"]) > co_Ddim
    
    criteria3_d <- any(fibrinogen, Ddimers)
    
    ## acute GI symptoms
    GIsymp <- row["symp_GI_NS"] == TRUE | row["symp_GI_abdopain"] == TRUE | row["symp_GI_vomiting"] == TRUE | row["symp_GI_diarrh"] == TRUE | row["symp_GI_colitis"] == TRUE 
    
    criteria3_e <- any(GIsymp)
    
    criteria3 <- sum(criteria3_a, criteria3_b, criteria3_c, criteria3_d, criteria3_e, na.rm = TRUE) >= 2
      
    # criteria 4: Elevated markers of inflammation (eg, ESR, CRP, or procalcitonin)
    neutrophilia <- as.numeric(row["lab_neutrophils"]) > co_neutrophilia
    elevated_CRP <- (as.numeric(row["lab_CRP_admis"]) >= co_CRP) | (as.numeric(row["lab_CRP_NS"]) >= co_CRP) | (as.numeric(row["lab_CRP_peak"]) >= co_CRP )
  #  print(paste0(pat_id, elevated_CRP, row["lab_CRP_peak"]))
    lymphopenia <- as.numeric(row["lab_lymphocytes_lowest"]) < co_lympho

    ferritin <- (as.numeric(row["lab_ferritin_NS"]) > co_ferritin | as.numeric(row["lab_ferritin_admis"]) > co_ferritin | as.numeric(row["lab_ferritin_peak"]) > co_ferritin)
    albumin <- as.numeric(row["lab_albumin_admis"]) < co_albu | as.numeric(row["lab_albumin_lowest"]) < co_albu | as.numeric(row["lab_albumin_NS"]) < co_albu
    PCT <- as.numeric(row["lab_PCT_admis"]) > co_PCT | as.numeric(row["lab_PCT_peak"]) > co_PCT | as.numeric(row["lab_PCT_NS"]) > co_PCT 
    LDH <- as.numeric(row["lab_LDH"]) > co_LDH
    IL6 <- as.numeric(row["lab_IL6"]) > co_IL6
    ESR <- as.numeric(row["lab_ESR"]) > co_ESR

    criteria4 <- any(neutrophilia, elevated_CRP, lymphopenia, ferritin, albumin, PCT, LDH, IL6, ESR)

    # criteria 5: No other obvious microbial cause of inflammation
    criteria5 <- TRUE
    
    # criteria 6: COVID pos?
    PCR_pos <- row["covid_PCR_pos"] == TRUE
    stool_pos <- row["covid_PCR_stool_pos"] == TRUE
    closecontact <- row["covid_closecontact"] == TRUE
    IgA <- row["covid_IgA_pos"] == TRUE
    IgM <- row["covid_IgM_pos"] == TRUE    
    IgG <- row["covid_IgG_pos"] == TRUE    
    any_sero <- row["covid_sero_pos"] == TRUE
    
    criteria6 <- any(PCR_pos, stool_pos, closecontact, IgA, IgM, IgG, any_sero)
    
    if (NA %in% c(criteria1, criteria2, criteria3, criteria4, criteria5, criteria6)){
      criteria_fulfilled <- NA
    } else if (FALSE %in% c(criteria1, criteria2, criteria3, criteria4, criteria5, criteria6)){
      criteria_fulfilled <- FALSE
    } else if (sum(criteria1, criteria2, criteria3, criteria4, criteria5, criteria6, na.rm = TRUE) == 6){
      criteria_fulfilled <- TRUE
    } else {
      criteria_fulfilled <- FALSE
    }

    return(c(pat_id, "criteria1_age" = criteria1, "criteria2_fever" = criteria2, "criteria3_clinical" = criteria3, "criteria4_inflamm" = criteria4, "criteria5_noAlt" = criteria5, "criteria6_recentExposure" = criteria6, "criteria_fulfilled" = criteria_fulfilled))
})


WHO_fulfilled <- WHO_fulfilled %>% t() %>% as_tibble()
WHO_fulfilled <- type_convert(WHO_fulfilled)
WHO_fulfilled_heatmap <- WHO_fulfilled
cols <- sapply(WHO_fulfilled_heatmap, is.logical)
WHO_fulfilled_heatmap[,cols] <- lapply(WHO_fulfilled_heatmap[,cols], as.numeric)
WHO_fulfilled_heatmap_melt <- WHO_fulfilled_heatmap %>% melt()
WHO_fulfilled_heatmap_melt[is.na(WHO_fulfilled_heatmap_melt)] <- 2

skim(WHO_fulfilled)
Data summary
Name WHO_fulfilled
Number of rows 95
Number of columns 8
_______________________
Column type frequency:
character 1
logical 7
________________________
Group variables None

Variable type: character

skim_variable n_missing complete_rate min max empty n_unique whitespace
patientID_int 0 1 9 10 0 95 0

Variable type: logical

skim_variable n_missing complete_rate mean count
criteria1_age 0 1.00 1.00 TRU: 95
criteria2_fever 0 1.00 1.00 TRU: 95
criteria3_clinical 0 1.00 0.98 TRU: 93, FAL: 2
criteria4_inflamm 0 1.00 1.00 TRU: 95
criteria5_noAlt 0 1.00 1.00 TRU: 95
criteria6_recentExposure 9 0.91 1.00 TRU: 86
criteria_fulfilled 9 0.91 0.98 TRU: 84, FAL: 2

9.4 Summary

criteria_summary <- data.frame(PIMS_TS_fulfilled %>% select(criteria_fulfilled), CDC_fulfilled %>% select(criteria_fulfilled), WHO_fulfilled %>% select(criteria_fulfilled))
colnames(criteria_summary) <- c("PIMS-TS", "CDC", "WHO")

cols <- sapply(criteria_summary, is.logical)
criteria_summary[,cols] <- lapply(criteria_summary[,cols], as.numeric)

criteria_summary <- criteria_summary %>% melt() %>% 
                          group_by(variable) %>% 
                          summarise(fulfilled = sum(value == 1, na.rm = TRUE), not_fulfilled = sum(value == 0, na.rm = TRUE), not_assessable = sum(is.na(value)))
criteria_summary$sum <- rowSums(criteria_summary[,-1])

criteria_summary_melt <- criteria_summary %>% melt()
colnames(criteria_summary_melt) <- c("center", "fulfilled", "count")

fill_bar <- ggplot(criteria_summary_melt %>% filter(fulfilled != 'sum'), aes(x = center, y = count, fill = fulfilled)) + 
      geom_bar(stat = "identity", position = "fill") + theme_bw() + 
      labs(y = "ratio", title = "Single cases meeting which criteria", subtitle = paste0("percent of total (n = ", max(criteria_summary_melt$count) ,")")) +
        scale_fill_manual(values = wes_palette("Royal1")[c(1,2,4)])

dodge_bar <- ggplot(criteria_summary_melt %>% filter(fulfilled != 'sum'), aes(x = center, y = count, fill = fulfilled)) + 
      geom_bar(stat = "identity", position = "dodge") + theme_bw() + 
      labs(y = "n", title = "Single cases meeting which criteria", subtitle = "absolute values") +
        scale_fill_manual(values = wes_palette("Royal1")[c(1,2,4)])

ggarrange(dodge_bar, fill_bar, legend = "bottom", common.legend = TRUE)

10 Association of case definition with outcome

10.1 Unfavourable course

A new variable ‘unfavourable course’ made, which contains the following:

  • symp_cardiovasc_cordilat
  • symp_cardiovasc_aneurysm
  • symp_cardiovasc_shock
  • outcome_death
  • critcare_MV
  • critcare_ECMO
  • critcare_RRT
  • critcare_inotrop
  • admis_PICU_admis

Mild presentation means all of the above are either 0 or NA.

Cases with missing values in case defintions are removed.

10.2 PICU candidate

A new variable ‘PICU candidate’ made, which contains the following:

  • symp_cardiovasc_shock
  • outcome_death
  • critcare_MV
  • critcare_ECMO
  • critcare_RRT
  • critcare_inotrop
  • admis_PICU_admis

Mild presentation means all of the above are either 0 or NA.

Cases with missing values in case defintions are removed.

11 SessionInfo

## R version 3.6.3 (2020-02-29)
## Platform: x86_64-apple-darwin15.6.0 (64-bit)
## Running under: macOS Catalina 10.15.5
## 
## Matrix products: default
## BLAS:   /Library/Frameworks/R.framework/Versions/3.6/Resources/lib/libRblas.0.dylib
## LAPACK: /Library/Frameworks/R.framework/Versions/3.6/Resources/lib/libRlapack.dylib
## 
## locale:
## [1] en_US.UTF-8/en_US.UTF-8/en_US.UTF-8/C/en_US.UTF-8/en_US.UTF-8
## 
## attached base packages:
## [1] stats     graphics  grDevices utils     datasets  methods   base     
## 
## other attached packages:
##  [1] gdtools_0.2.1      padr_0.5.2         wesanderson_0.3.6  see_0.5.1         
##  [5] UpSetR_1.4.0       skimr_2.1.1        psych_1.9.12.31    zoo_1.8-7         
##  [9] DT_0.13            naniar_0.5.2       cowplot_1.0.0      ggpubr_0.2.5      
## [13] magrittr_1.5       ggbeeswarm_0.6.0   ggExtra_0.9        gridExtra_2.3     
## [17] ggrepel_0.8.2      scales_1.1.1       RColorBrewer_1.1-2 broom_0.5.5       
## [21] reshape2_1.4.3     httr_1.4.1         readxl_1.3.1       forcats_0.5.0     
## [25] stringr_1.4.0      dplyr_0.8.5        purrr_0.3.4        readr_1.3.1       
## [29] tidyr_1.0.2        tibble_3.0.1       ggplot2_3.3.1      tidyverse_1.3.0   
## 
## loaded via a namespace (and not attached):
##  [1] nlme_3.1-144      fs_1.4.0          lubridate_1.7.4   insight_0.8.5    
##  [5] repr_1.1.0        tools_3.6.3       backports_1.1.7   R6_2.4.1         
##  [9] vipor_0.4.5       DBI_1.1.0         colorspace_1.4-1  withr_2.2.0      
## [13] tidyselect_1.1.0  mnormt_1.5-6      compiler_3.6.3    cli_2.0.2        
## [17] rvest_0.3.5       xml2_1.3.0        labeling_0.3      bayestestR_0.7.0 
## [21] ggridges_0.5.2    systemfonts_0.1.1 digest_0.6.25     svglite_1.2.3    
## [25] rmarkdown_2.1     base64enc_0.1-3   pkgconfig_2.0.3   htmltools_0.4.0  
## [29] highr_0.8         dbplyr_1.4.2      fastmap_1.0.1     htmlwidgets_1.5.1
## [33] rlang_0.4.6       rstudioapi_0.11   shiny_1.4.0.2     farver_2.0.3     
## [37] generics_0.0.2    jsonlite_1.6.1    crosstalk_1.1.0.1 parameters_0.8.0 
## [41] Rcpp_1.0.4        munsell_0.5.0     fansi_0.4.1       lifecycle_0.2.0  
## [45] visdat_0.5.3      stringi_1.4.6     yaml_2.2.1        plyr_1.8.6       
## [49] grid_3.6.3        parallel_3.6.3    promises_1.1.0    crayon_1.3.4     
## [53] miniUI_0.1.1.1    lattice_0.20-38   haven_2.2.0       hms_0.5.3        
## [57] knitr_1.28        pillar_1.4.4      ggsignif_0.6.0    effectsize_0.3.1 
## [61] reprex_0.3.0      glue_1.4.1        evaluate_0.14     modelr_0.1.6     
## [65] vctrs_0.3.0       httpuv_1.5.2      cellranger_1.1.0  gtable_0.3.0     
## [69] assertthat_0.2.1  xfun_0.12         mime_0.9          xtable_1.8-4     
## [73] later_1.0.0       beeswarm_0.2.3    ellipsis_0.3.1
LS0tCnRpdGxlOiAiTXVsdGlzeXN0ZW0gaW5mbGFtbWF0b3J5IHN5bmRyb21lIGluIGNoaWxkcmVuIHJlbGF0ZWQgdG8gQ09WSUQtMTk6IGEgc3lzdGVtYXRpYyByZXZpZXciCnN1YnRpdGxlOiAiRXh0ZW5kZWQgbWV0aG9kcyBhbmQgZGF0YSBhbmFseXNpcyIKYXV0aG9yOiAiTGV2aSBIb3N0ZSwgUnViZW4gVmFuIFBhZW1lbCwgRmlsb21lZW4gSGFlcnluY2siCmRhdGU6ICJgciBmb3JtYXQoU3lzLnRpbWUoKSwgJyVkICVCLCAlWSwgJUg6JU06JVMnKWAiCm91dHB1dDoKICBodG1sX2RvY3VtZW50OgogICAgY29kZV9mb2xkaW5nOiBoaWRlCiAgICBoaWdobGlnaHQ6IGthdGUKICAgIG51bWJlcl9zZWN0aW9uczogeWVzCiAgICB0aGVtZTogY29zbW8KICAgIHRvYzogeWVzCiAgICB0b2NfZmxvYXQ6IHllcwogICAgZGZfcHJpbnQ6IHBhZ2VkCiAgICBjb2RlX2Rvd25sb2FkOiB0cnVlCiAgICBmaWdfY2FwdGlvbjogeWVzCi0tLQoKPHN0eWxlPgpib2R5IHsKdGV4dC1hbGlnbjoganVzdGlmeX0KPC9zdHlsZT4KCgojIEludHJvZHVjdGlvbgpJbiB0aGlzIFJNYXJrZG93biBmaWxlLCB0aGUgZXh0ZW5kZWQgbWV0aG9kcyBhbmQgZGF0YS1hbmFseXNpcyBmb3IgdGhlIG1hbnVzY3JpcHQgIk11bHRpc3lzdGVtIGluZmxhbW1hdG9yeSBzeW5kcm9tZSBpbiBjaGlsZHJlbiByZWxhdGVkIHRvIENPVklELTE5OiBhIHN5c3RlbWF0aWMgcmV2aWV3IiBpcyBkZXNjcmliZWQuIFRoZSBjb21wbGV0ZSBkYXRhLWFuYWx5c2lzIGNhbiBiZSByZXByb2R1Y2VkIGZyb20gdGhlIGRhdGEgY29sbGVjdGlvbiBzaGVldCAoaW4gLnhscyBmb3JtYXQpLCBwcm92aWRlZCBpbiB0aGUgc3VwcGxlbWVudGFyeSBmaWxlcyBvZiB0aGUgbWFudXNjcmlwdCBvciBvbiBbR2l0aHViXShodHRwczovL2dpdGh1Yi5jb20vcm12cGFlbWUvUElNU19UUykuCgpQcmlvciB0byBjb25kdWN0aW5nIHRoZeKAr3JldmlldywgdGhl4oCvc3R1ZHnigK9wcm90b2NvbOKAr3dhcyBwdWJsaXNoZWQgb24gdGhl4oCvW1BST1NQRVJP4oCvc3lzdGVtYXRpYyByZXZpZXfigK9yZWdpc3RlcuKAryhDUkQ0MjAyMDE4OTI0OCldKGh0dHBzOi8vd3d3LmNyZC55b3JrLmFjLnVrL3Byb3NwZXJvL2Rpc3BsYXlfcmVjb3JkLnBocD9SZWNvcmRJRD0xODkyNDgpLgoKYGBge3Igc2V0dXAsIGluY2x1ZGU9VFJVRSwgd2FybmluZyA9IEZBTFNFLCBtZXNzYWdlID0gRkFMU0V9CmtuaXRyOjpvcHRzX2NodW5rJHNldChjYWNoZSA9IEZBTFNFLCB3YXJuaW5nID0gRkFMU0UsIG1lc3NhZ2UgPSBGQUxTRSkKb3B0aW9ucyhkaWdpdHMgPSAzKQpsaWJyYXJ5KHRpZHl2ZXJzZSkKcmVxdWlyZShyZWFkeGwpCnJlcXVpcmUoaHR0cikKcmVxdWlyZShyZXNoYXBlMikKcmVxdWlyZShicm9vbSkKcmVxdWlyZShSQ29sb3JCcmV3ZXIpCnJlcXVpcmUoc2NhbGVzKQpyZXF1aXJlKGdncmVwZWwpCnJlcXVpcmUoZ3JpZEV4dHJhKQpyZXF1aXJlKGdnRXh0cmEpCmxpYnJhcnkoZ2diZWVzd2FybSkKcmVxdWlyZShnZ3B1YnIpCmxpYnJhcnkoY293cGxvdCkKbGlicmFyeShuYW5pYXIpCnJlcXVpcmUoRFQpCnJlcXVpcmUoem9vKQpyZXF1aXJlKHBzeWNoKQpsaWJyYXJ5KHNraW1yKQpsaWJyYXJ5KFVwU2V0UikKbGlicmFyeShzZWUpCmxpYnJhcnkod2VzYW5kZXJzb24pCmxpYnJhcnkocGFkcikKCm9wdGlvbnMoc2NpcGVuPTk5OSkKCmNvX2hiIDwtIDEyCmNvX25ldXRyb3BoaWxpYSA8LSA4MDAwCmNvX0NSUCA8LSAxMApjb19seW1waG8gPC0gMTI1MApjb19maWJyaW5vIDwtIDQwMApjb19EZGltIDwtIDI1MApjb19mZXJyaXRpbiA8LSAzMDAKY29fYWxidSA8LSAzNApjb19QQ1QgPC0gMC40OQpjb19MREggPC0gMjgwCmNvX0lMNiA8LSAxNi40CmNvX0VTUiA8LSAyMgpjb19CTlAgPC0gMTAwCmNvX05UcHJvQk5QIDwtIDQwMApjb190cm9wbyA8LSA0MApjb19XQkMgPC0gMTEwMDAKY29fcGxhdGVsZXQgPC0gMTUwMDAwCmNvX3NvZGl1bSA8LSAxMzUKI2lucHV0ID0gZGZfY29ob3J0X2NvbnRyb2xzCiNmaW5kID0gIm1heCIKI3BhcmFtID0gIkNSUCIKCmNvbGxhcHNlX2xhYnZhbHNfY29ob3J0IDwtIGZ1bmN0aW9uKGlucHV0LCBmaW5kLCBwYXJhbSwgdmVyYm9zZSA9IEZBTFNFKXsKICBpZiAoZmluZCA9PSAibWF4Iil7CiAgICBkZiA8LSBpbnB1dCAlPiUgc2VsZWN0KGNvbnRhaW5zKHBhcmFtKSB8IGNvbnRhaW5zKCJjb2hvcnRfaWQiKSB8IGNvbnRhaW5zKCJjb2hvcnRfdHlwZSIpIHwgY29udGFpbnMoInRvdF9jYXNlc19uIikpCiAgICBpZiAodmVyYm9zZSA9PSBUUlVFKXsKICAgICAgcHJpbnQoIkNvbHVtbiBleHRyYWN0ZWQgZnJvbSBjb2hvcnRzOiIpCiAgICAgIHByaW50KGNvbG5hbWVzKGRmKSkKICAgIH0KICAgIGRmX21lZCA8LSBkZiAlPiUgc2VsZWN0KGNvbnRhaW5zKCJtZWQiKSkKICAgIGRmX21lZCA8LSB0eXBlX2NvbnZlcnQoZGZfbWVkKQogICAgZGZfbWVkIDwtIGRmX21lZCAlPiUgbXV0YXRlX2FsbChmdW5zKHJlcGxhY2VfbmEoLiwgLTk5OSkpKQogICAjIGNvbG5hbWVzKGRmX21lZClbbWF4LmNvbChkZl9tZWQsdGllcy5tZXRob2Q9ImZpcnN0IildCiAgICBkZl9tZWQgPC0gZGZfbWVkICU+JSBtdXRhdGUobWVkID0gYXMubnVtZXJpYyhhcHBseShkZl9tZWQsIDEsIG1heCkpKQogICAgCiAgICBkZl9taW4gPC0gZGYgJT4lIHNlbGVjdChjb250YWlucygiUTEiKSkKICAgIGRmX21pbiA8LSB0eXBlX2NvbnZlcnQoZGZfbWluKQogICAgZGZfbWluIDwtIGRmX21pbiAlPiUgbXV0YXRlX2FsbChmdW5zKHJlcGxhY2VfbmEoLiwgMCkpKQogICAgI2NvbG5hbWVzKGRmX21pbilbbWF4LmNvbChkZl9taW4sdGllcy5tZXRob2Q9ImZpcnN0IildCiAgICBkZl9taW4gPC0gZGZfbWluICU+JSBtdXRhdGUobWluID0gYXMubnVtZXJpYyhhcHBseShkZl9taW4sIDEsIG1heCkpKQogICAgCiAgICBkZl9tYXggPC0gZGYgJT4lIHNlbGVjdChjb250YWlucygiUTMiKSkKICAgIGRmX21heCA8LSB0eXBlX2NvbnZlcnQoZGZfbWF4KQogICAgZGZfbWF4IDwtIGRmX21heCAlPiUgbXV0YXRlX2FsbChmdW5zKHJlcGxhY2VfbmEoLiwgMCkpKQogICAgI2NvbG5hbWVzKGRmX21heClbbWF4LmNvbChkZl9tYXgsdGllcy5tZXRob2Q9ImZpcnN0IildCiAgICBkZl9tYXggPC0gZGZfbWF4ICU+JSBtdXRhdGUobWF4ID0gYXMubnVtZXJpYyhhcHBseShkZl9tYXgsIDEsIG1heCkpKQogICAgCiAgICBkZl9mdWxsIDwtIGNiaW5kKGRmICU+JSBzZWxlY3QoY29ob3J0X2lkLCBjb2hvcnRfdHlwZSwgdG90X2Nhc2VzX24pLCBkZl9tZWQgJT4lIHNlbGVjdChtZWQpLCBkZl9taW4gJT4lIHNlbGVjdChtaW4pLCBkZl9tYXggJT4lIHNlbGVjdChtYXgpKQogICAgZGZfZnVsbFtkZl9mdWxsID09IC05OTldIDwtIE5BCiAgICBuYW1lcyhkZl9mdWxsKVtuYW1lcyhkZl9mdWxsKSA9PSAnbWF4J10gPC0gcGFzdGUwKHBhcmFtLCAiX21heCIpCiAgICBuYW1lcyhkZl9mdWxsKVtuYW1lcyhkZl9mdWxsKSA9PSAnbWluJ10gPC0gcGFzdGUwKHBhcmFtLCAiX21pbiIpCiAgICBuYW1lcyhkZl9mdWxsKVtuYW1lcyhkZl9mdWxsKSA9PSAnbWVkJ10gPC0gcGFzdGUwKHBhcmFtLCAiX21lZCIpCiAgICBkZl9mdWxsJGRhdGFfZGVzY3IgPC0gIklRUiIKICAgIGRmX2Z1bGwkY29ob3J0X2lkIDwtIHBhc3RlMChkZl9mdWxsJGNvaG9ydF9pZCwgIiAobiA9ICIsIGFzLmNoYXJhY3RlcihkZl9mdWxsJHRvdF9jYXNlc19uKSwiKSIpCiAgICB3cml0ZS5jc3YoZGZfZnVsbCwgcGFzdGUwKCIuL2RhdGEvY29ob3J0XyIsIHBhcmFtLCAiLmNzdiIpKQogICAgcHJpbnQoZGF0YXRhYmxlKGRmX2Z1bGwsIGNhcHRpb24gPSBwYXN0ZTAoIm92ZXJ2aWV3IG9mICIsIHBhcmFtKSkpCiAgICByZXR1cm4oZGZfZnVsbCkKICB9CiAgICBlbHNlIGlmIChmaW5kID09ICJtaW4iKXsKICAgIGRmIDwtIGlucHV0ICU+JSBzZWxlY3QoY29udGFpbnMocGFyYW0pIHwgY29udGFpbnMoImNvaG9ydF9pZCIpIHwgY29udGFpbnMoImNvaG9ydF90eXBlIikgfCBjb250YWlucygidG90X2Nhc2VzX24iKSkKICAgIGlmICh2ZXJib3NlID09IFRSVUUpewogICAgcHJpbnQoIkNvbHVtbiBleHRyYWN0ZWQgZnJvbSBjb2hvcnRzOiIpCiAgICBwcmludChjb2xuYW1lcyhkZikpCiAgICB9CiAgICBkZl9tZWQgPC0gZGYgJT4lIHNlbGVjdChjb250YWlucygibWVkIikpCiAgICBkZl9tZWQgPC0gdHlwZV9jb252ZXJ0KGRmX21lZCkKICAgIGRmX21lZCA8LSBkZl9tZWQgJT4lIG11dGF0ZV9hbGwoZnVucyhyZXBsYWNlX25hKC4sIDFlNikpKQogICAjIGNvbG5hbWVzKGRmX21lZClbbWF4LmNvbChkZl9tZWQsdGllcy5tZXRob2Q9ImZpcnN0IildCiAgICBkZl9tZWQgPC0gZGZfbWVkICU+JSBtdXRhdGUobWVkID0gYXMubnVtZXJpYyhhcHBseShkZl9tZWQsIDEsIG1pbikpKQogICAgCiAgICBkZl9taW4gPC0gZGYgJT4lIHNlbGVjdChjb250YWlucygiUTEiKSkKICAgIGRmX21pbiA8LSB0eXBlX2NvbnZlcnQoZGZfbWluKQogICAgZGZfbWluIDwtIGRmX21pbiAlPiUgbXV0YXRlX2FsbChmdW5zKHJlcGxhY2VfbmEoLiwgMWU2KSkpCiAgICAjY29sbmFtZXMoZGZfbWluKVttYXguY29sKGRmX21pbix0aWVzLm1ldGhvZD0iZmlyc3QiKV0KICAgIGRmX21pbiA8LSBkZl9taW4gJT4lIG11dGF0ZShtaW4gPSBhcy5udW1lcmljKGFwcGx5KGRmX21pbiwgMSwgbWluKSkpCiAgICAKICAgIGRmX21heCA8LSBkZiAlPiUgc2VsZWN0KGNvbnRhaW5zKCJRMyIpKQogICAgZGZfbWF4IDwtIHR5cGVfY29udmVydChkZl9tYXgpCiAgICBkZl9tYXggPC0gZGZfbWF4ICU+JSBtdXRhdGVfYWxsKGZ1bnMocmVwbGFjZV9uYSguLCAxZTYpKSkKICAgICNjb2xuYW1lcyhkZl9tYXgpW21heC5jb2woZGZfbWF4LHRpZXMubWV0aG9kPSJmaXJzdCIpXQogICAgZGZfbWF4IDwtIGRmX21heCAlPiUgbXV0YXRlKG1heCA9IGFzLm51bWVyaWMoYXBwbHkoZGZfbWF4LCAxLCBtaW4pKSkKICAgIAogICAgZGZfZnVsbCA8LSBjYmluZChkZiAlPiUgc2VsZWN0KGNvaG9ydF9pZCwgY29ob3J0X3R5cGUsIHRvdF9jYXNlc19uKSwgZGZfbWVkICU+JSBzZWxlY3QobWVkKSwgZGZfbWluICU+JSBzZWxlY3QobWluKSwgZGZfbWF4ICU+JSBzZWxlY3QobWF4KSkKICAgIGRmX2Z1bGxbZGZfZnVsbCA9PSAxZTZdIDwtIE5BCiAgICBuYW1lcyhkZl9mdWxsKVtuYW1lcyhkZl9mdWxsKSA9PSAnbWF4J10gPC0gcGFzdGUwKHBhcmFtLCAiX21heCIpCiAgICBuYW1lcyhkZl9mdWxsKVtuYW1lcyhkZl9mdWxsKSA9PSAnbWluJ10gPC0gcGFzdGUwKHBhcmFtLCAiX21pbiIpCiAgICBuYW1lcyhkZl9mdWxsKVtuYW1lcyhkZl9mdWxsKSA9PSAnbWVkJ10gPC0gcGFzdGUwKHBhcmFtLCAiX21lZCIpCiAgICBkZl9mdWxsJGRhdGFfZGVzY3IgPC0gIklRUiIKICAgIGRmX2Z1bGwkY29ob3J0X2lkIDwtIHBhc3RlMChkZl9mdWxsJGNvaG9ydF9pZCwgIiAobiA9ICIsIGFzLmNoYXJhY3RlcihkZl9mdWxsJHRvdF9jYXNlc19uKSwiKSIpCiAgICB3cml0ZS5jc3YoZGZfZnVsbCwgcGFzdGUwKCIuL2RhdGEvY29ob3J0XyIsIHBhcmFtLCAiLmNzdiIpKQogICAgcHJpbnQoZGF0YXRhYmxlKGRmX2Z1bGwsIGNhcHRpb24gPSBwYXN0ZTAoIm92ZXJ2aWV3IG9mICIsIHBhcmFtKSkpCiAgICByZXR1cm4oZGZfZnVsbCkKICB9Cn0KCiNpbnB1dCA9IGRmX3NpbmdsZWNhc2VzCiNmaW5kID0gIm1heCIKI3BhcmFtID0gIkNSUCIKCmNvbGxhcHNlX2xhYnZhbHNfc2luZ2xlIDwtIGZ1bmN0aW9uKGlucHV0LCBmaW5kLCBwYXJhbSwgdmVyYm9zZSA9IEZBTFNFKXsKICBpZiAoZmluZCA9PSAibWF4Iil7CiAgICBkZiA8LSBpbnB1dCAlPiUgc2VsZWN0KGNvbnRhaW5zKHBhcmFtKSB8IGNvbnRhaW5zKCJjb2hvcnRfaWQiKSkKICAgIGlmICh2ZXJib3NlID09IFRSVUUpewogICAgcHJpbnQoIkNvbHVtbiBleHRyYWN0ZWQgZnJvbSBzaW5nbGUgY2FzZXM6IikKICAgIHByaW50KGNvbG5hbWVzKGRmKSkKICAgIH0KICAgIGRmX2NvbGwgPC0gZGYgJT4lIG11dGF0ZV9hbGwoZnVucyhyZXBsYWNlX25hKC4sIC05OTkpKSkKICAgIGRmX2NvbGwgPC0gdHlwZV9jb252ZXJ0KGRmX2NvbGwpCiAgICMgY29sbmFtZXMoZGZfbWVkKVttYXguY29sKGRmX21lZCx0aWVzLm1ldGhvZD0iZmlyc3QiKV0KICAgIGRmX2NvbGwgPC0gZGZfY29sbCAlPiUgbXV0YXRlKG1heCA9IGFzLm51bWVyaWMoYXBwbHkoZGZfY29sbCwgMSwgbWF4KSkpCiAgICAKICAgIGRmX2NvbGxbZGZfY29sbCA9PSAtOTk5XSA8LSBOQQogICAgbmFtZXMoZGZfY29sbClbbmFtZXMoZGZfY29sbCkgPT0gJ21heCddIDwtIHBhc3RlMChwYXJhbSwgIl9tYXgiKQogICAgZGZfY29sbCRkYXRhX2Rlc2NyIDwtICJJUVIiCiAgICBkZl9jb2xsJGNvaG9ydF9pZCA8LSBwYXN0ZTAoInNpbmdsZSBjYXNlcyAobiA9ICIsIGFzLmNoYXJhY3RlcihuX3NpbmdsZV9jYXNlcyksIikiKQogICAgd3JpdGUuY3N2KHNraW0oZGZfY29sbCksIHBhc3RlMCgiLi9kYXRhL3NpbmdsZWNhc2VzXyIsIHBhcmFtLCAiLmNzdiIpKQogICAgcmV0dXJuKGRmX2NvbGwpCiAgfQogICAgZWxzZSBpZiAoZmluZCA9PSAibWluIil7CiAgICBkZiA8LSBpbnB1dCAlPiUgc2VsZWN0KGNvbnRhaW5zKHBhcmFtKSB8IGNvbnRhaW5zKCJjb2hvcnRfaWQiKSkKICAgIGlmICh2ZXJib3NlID09IFRSVUUpewogICAgcHJpbnQoIkNvbHVtbiBleHRyYWN0ZWQgZnJvbSBzaW5nbGUgY2FzZXM6IikKICAgIHByaW50KGNvbG5hbWVzKGRmKSkKICAgIH0KICAgIGRmX2NvbGwgPC0gZGYgJT4lIG11dGF0ZV9hbGwoZnVucyhyZXBsYWNlX25hKC4sIDFlNikpKQogICAjIGNvbG5hbWVzKGRmX21lZClbbWF4LmNvbChkZl9tZWQsdGllcy5tZXRob2Q9ImZpcnN0IildCiAgICBkZl9jb2xsIDwtIGRmX2NvbGwgJT4lIG11dGF0ZShtaW4gPSBhcy5udW1lcmljKGFwcGx5KGRmX2NvbGwsIDEsIG1pbikpKQogICAgCiAgICBkZl9jb2xsW2RmX2NvbGwgPT0gMWU2XSA8LSBOQQogICAgbmFtZXMoZGZfY29sbClbbmFtZXMoZGZfY29sbCkgPT0gJ21pbiddIDwtIHBhc3RlMChwYXJhbSwgIl9taW4iKQogICAgZGZfY29sbCRjb2hvcnRfaWQgPC0gcGFzdGUwKCJzaW5nbGUgY2FzZXMgKG4gPSAiLCBhcy5jaGFyYWN0ZXIobl9zaW5nbGVfY2FzZXMpLCIpIikKICAgIHdyaXRlLmNzdihza2ltKGRmX2NvbGwpLCBwYXN0ZTAoIi4vZGF0YS9zaW5nbGVjYXNlc18iLCBwYXJhbSwgIi5jc3YiKSkKICAgIHJldHVybihkZl9jb2xsKQogIH0KfQoKCm1vdmVtZSA8LSBmdW5jdGlvbiAoZGYsIG1vdmVjb21tYW5kKSB7CiAgaW52ZWMgPC0gbmFtZXMoZGYpCiAgCiAgbW92ZWNvbW1hbmQgPC0gbGFwcGx5KHN0cnNwbGl0KHN0cnNwbGl0KG1vdmVjb21tYW5kLCAiOyIpW1sxXV0sIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiLHxcXHMrIiksIGZ1bmN0aW9uKHgpIHhbeCAhPSAiIl0pCiAgbW92ZWxpc3QgPC0gbGFwcGx5KG1vdmVjb21tYW5kLCBmdW5jdGlvbih4KSB7CiAgICBXaGVyZSA8LSB4W3doaWNoKHggJWluJSBjKCJiZWZvcmUiLCAiYWZ0ZXIiLCAiZmlyc3QiLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgImxhc3QiKSk6bGVuZ3RoKHgpXQogICAgVG9Nb3ZlIDwtIHNldGRpZmYoeCwgV2hlcmUpCiAgICBsaXN0KFRvTW92ZSwgV2hlcmUpCiAgfSkKICBteVZlYyA8LSBpbnZlYwogIGZvciAoaSBpbiBzZXFfYWxvbmcobW92ZWxpc3QpKSB7CiAgICB0ZW1wIDwtIHNldGRpZmYobXlWZWMsIG1vdmVsaXN0W1tpXV1bWzFdXSkKICAgIEEgPC0gbW92ZWxpc3RbW2ldXVtbMl1dWzFdCiAgICBpZiAoQSAlaW4lIGMoImJlZm9yZSIsICJhZnRlciIpKSB7CiAgICAgIGJhIDwtIG1vdmVsaXN0W1tpXV1bWzJdXVsyXQogICAgICBpZiAoQSA9PSAiYmVmb3JlIikgewogICAgICAgIGFmdGVyIDwtIG1hdGNoKGJhLCB0ZW1wKSAtIDEKICAgICAgfQogICAgICBlbHNlIGlmIChBID09ICJhZnRlciIpIHsKICAgICAgICBhZnRlciA8LSBtYXRjaChiYSwgdGVtcCkKICAgICAgfQogICAgfQogICAgZWxzZSBpZiAoQSA9PSAiZmlyc3QiKSB7CiAgICAgIGFmdGVyIDwtIDAKICAgIH0KICAgIGVsc2UgaWYgKEEgPT0gImxhc3QiKSB7CiAgICAgIGFmdGVyIDwtIGxlbmd0aChteVZlYykKICAgIH0KICAgIG15VmVjIDwtIGFwcGVuZCh0ZW1wLCB2YWx1ZXMgPSBtb3ZlbGlzdFtbaV1dW1sxXV0sIGFmdGVyID0gYWZ0ZXIpCiAgfQogIAogIGRmWyxtYXRjaChteVZlYywgbmFtZXMoZGYpKV0KfQoKbWFrZUJhcnBsb3QgPC0gZnVuY3Rpb24odmFyX2lkX2NvaG9ydCwgdmFyX2lkX3NpbmdsZSwgdmFyX2lkKXsKCiAgICAgICAgbl9jb2hvcnQgPC0gZGZfY29ob3J0ICU+JSBzZWxlY3QodG90X2Nhc2VzX24pICU+JSBzdW0oKSMsIG91dGNvbWVfZGVhdGhfbikKICAgICAgICB2YXJfY29ob3J0IDwtIGRmX2NvaG9ydFt2YXJfaWRfY29ob3J0XSAlPiUgc3VtKC4sIG5hLnJtID0gVFJVRSkjLCBvdXRjb21lX2RlYXRoX24pCiAgICAgICAgCiAgICAgICAgbl9zaW5nbGUgPC0gZGZfc2luZ2xlY2FzZXMgJT4lIG5yb3coKQogICAgICAgIAogICAgICAgIHZhcl9zaW5nbGUgPC0gZGZfc2luZ2xlY2FzZXMgJT4lIGZpbHRlcihnZXQodmFyX2lkX3NpbmdsZSkgPT0gVFJVRSkgJT4lIG5yb3coKQogICAgICAgIAogICAgICAgIG5fYWxsIDwtIG5fY29ob3J0ICsgbl9zaW5nbGUKICAgICAgICB2YXJfYWxsIDwtIHZhcl9jb2hvcnQgKyB2YXJfc2luZ2xlCiAgICAgICAgCiAgICAgICAgYmFyX2RmX2FicyA8LSBkYXRhLmZyYW1lKHggPSBjKCJjb2hvcnQiLCAiY29ob3J0IiwgInNpbmdsZSBjYXNlcyIsICJzaW5nbGUgY2FzZXMiLCAiYWxsIiwgImFsbCIpLCBjb2wgPSBjKCJ0b3RhbCIsIHZhcl9pZCwgInRvdGFsIiwgdmFyX2lkLCAidG90YWwiLCB2YXJfaWQpLCB2YWxzID0gYyhuX2NvaG9ydCwgdmFyX2NvaG9ydCwgbl9zaW5nbGUsIHZhcl9zaW5nbGUsIG5fYWxsLCB2YXJfYWxsKSApCiAgICAgICAgCiAgICAgICAgYmFyX2RmX3ByY3QgPC0gZGF0YS5mcmFtZSh4ID0gYygiY29ob3J0IiwgImNvaG9ydCIsICJzaW5nbGUgY2FzZXMiLCAic2luZ2xlIGNhc2VzIiwgImFsbCIsICJhbGwiKSwgY29sID0gYyhwYXN0ZTAodmFyX2lkLCAiIC0iKSwgcGFzdGUwKHZhcl9pZCwgIiArIiksIHBhc3RlMCh2YXJfaWQsICIgLSIpLCBwYXN0ZTAodmFyX2lkLCAiICsiKSwgcGFzdGUwKHZhcl9pZCwgIiAtIiksIHBhc3RlMCh2YXJfaWQsICIgKyIpKSwgdmFscyA9IGMoMTAwLSh2YXJfY29ob3J0L25fY29ob3J0KjEwMCksIHZhcl9jb2hvcnQvbl9jb2hvcnQqMTAwLCAxMDAtKHZhcl9zaW5nbGUvbl9zaW5nbGUqMTAwKSwgdmFyX3NpbmdsZS9uX3NpbmdsZSoxMDAsIDEwMC0odmFyX2FsbC9uX2FsbCoxMDApLCB2YXJfYWxsL25fYWxsKjEwMCkgKQoKICAgICAgICAKICAgICAgICBwX2FicyA8LSBnZ3Bsb3QoYmFyX2RmX2FicywgYWVzKHggPSB4LCB5ID0gIHZhbHMsIGZpbGwgPSBjb2wpKSArCiAgICAgICAgICAgIGdlb21fYmFyKHN0YXQgPSAiaWRlbnRpdHkiLCBwb3NpdGlvbiA9ICJkb2RnZSIpICsKICAgICAgICAgICAgdGhlbWVfYncoKSArIAogICAgICAgICAgICBsYWJzKHRpdGxlID0gcGFzdGUwKCJUb3RhbCBjYXNlcyB2cyAiLCB2YXJfaWQpLCBzdWJ0aXRsZSA9ICJBYnNvbHV0ZSBudW1iZXJzIiwgeCA9ICJncm91cCIsIHkgPSAibiIsIGNvbCA9ICIiKSArCiAgc2NhbGVfZmlsbF9tYW51YWwodmFsdWVzID0gd2VzX3BhbGV0dGUoIlJveWFsMSIpKQogICAgICAgIAogICAgICAgIAogICAgICAgIHBfcHJjdCA8LSBnZ3Bsb3QoYmFyX2RmX3ByY3QsIGFlcyh4ID0geCwgeSA9ICB2YWxzLCBmaWxsID0gY29sKSkgKwogICAgICAgICAgICBnZW9tX2JhcihzdGF0ID0gImlkZW50aXR5IiwgcG9zaXRpb24gPSAiZmlsbCIpICsKICAgICAgICAgICAgdGhlbWVfYncoKSArIAogICAgICAgICAgICBsYWJzKHRpdGxlID0gcGFzdGUwKHZhcl9pZCksIHN1YnRpdGxlID0gIlBlcmNlbnQiLCB4ID0gImdyb3VwIiwgeSA9ICIlIiwgY29sID0gIiIpICArCiAgICBzY2FsZV95X2NvbnRpbnVvdXMobGFiZWxzID0gc2NhbGVzOjpwZXJjZW50KSsKICBzY2FsZV9maWxsX21hbnVhbCh2YWx1ZXMgPSB3ZXNfcGFsZXR0ZSgiUm95YWwxIikpCiAgICAgICAgCiAgICAgICAgZ2dhcnJhbmdlKHBfYWJzLCBwX3ByY3QsIGxlZ2VuZCA9ICJib3R0b20iKQogIAp9CgptYWtlSGVhdG1hcF9jb2hvcnQgPC0gZnVuY3Rpb24ocGFyYW0xLCBjb2xuYW1lX3NpbmdsZSwgZXhjbHVkZV9zaW5nbGUgPSBOVUxMLCBwbG90dGl0bGUsIHRleHRzaXplID0gMyl7CiAgdmFyX2NvaG9ydCA8LSBkZl9jb2hvcnQgJT4lIHNlbGVjdCgoImNvaG9ydF9pZCIpIHwgInRvdF9jYXNlc19uIiB8ICggY29udGFpbnMocGFyYW0xKSAmIGNvbnRhaW5zKCJfbiIpKSkKICB2YXJfY29ob3J0JGNvaG9ydF9pZCA8LSBwYXN0ZTAodmFyX2NvaG9ydCRjb2hvcnRfaWQsICIgKG4gPSAiLCBhcy5jaGFyYWN0ZXIodmFyX2NvaG9ydCR0b3RfY2FzZXNfbiksIikiKQogIHZhcl9jb2hvcnQgPC0gdmFyX2NvaG9ydCAlPiUgCiAgICBnYXRoZXIodmFyaWFibGUsIHZhbHVlLCAzOm5jb2wodmFyX2NvaG9ydCkpICU+JSBncm91cF9ieShjb2hvcnRfaWQsIHZhcmlhYmxlKSAlPiUgc3VtbWFyaXplKHByY3QgPSB2YWx1ZS90b3RfY2FzZXNfbioxMDApCiAgdmFyX2NvaG9ydCR2YXJpYWJsZSA8LSBzdWIoIl9uIiwgIiIsIHZhcl9jb2hvcnQkdmFyaWFibGUpCgppZiAoIWlzLm51bGwoZXhjbHVkZV9zaW5nbGUpKXsKICB2YXJfc2luZ2xlIDwtIGRmX3NpbmdsZWNhc2VzICU+JSBzZWxlY3QoLWNvbnRhaW5zKGV4Y2x1ZGVfc2luZ2xlKSkKICB2YXJfc2luZ2xlIDwtIHZhcl9zaW5nbGUgJT4lIHNlbGVjdChjb250YWlucyhjb2xuYW1lX3NpbmdsZSkpCn0gZWxzZQp7CiAgdmFyX3NpbmdsZSA8LSBkZl9zaW5nbGVjYXNlcyAlPiUgc2VsZWN0KGNvbnRhaW5zKGNvbG5hbWVfc2luZ2xlKSkKfQoKICMlPiUgc2VsZWN0KC1jb250YWlucygiYW55IikpCmNvbHMgPC0gc2FwcGx5KHZhcl9zaW5nbGUsIGlzLmxvZ2ljYWwpCnZhcl9zaW5nbGVbLGNvbHNdIDwtIGxhcHBseSh2YXJfc2luZ2xlWyxjb2xzXSwgYXMubnVtZXJpYykKdmFyX3NpbmdsZSA8LSBjb2xTdW1zKHZhcl9zaW5nbGUsIG5hLnJtID0gVFJVRSkKdmFyX3NpbmdsZSA8LSB2YXJfc2luZ2xlL25yb3coZGZfc2luZ2xlY2FzZXMpKjEwMAp2YXJfc2luZ2xlIDwtIGFzLmRhdGEuZnJhbWUodmFyX3NpbmdsZSkgJT4lIHJvd25hbWVzX3RvX2NvbHVtbigpCnZhcl9zaW5nbGUkY29ob3J0X2lkIDwtIHBhc3RlMCgic2luZ2xlIGNhc2VzIChuID0gIiwgbl9zaW5nbGVfY2FzZXMsIikiKQpjb2xuYW1lcyh2YXJfc2luZ2xlKSA8LSBjKCJ2YXJpYWJsZSIsICJwcmN0IiwgImNvaG9ydF9pZCIpCgoKbWlzc2luZyA8LSBzZXRkaWZmKHZhcl9zaW5nbGUkdmFyaWFibGUsIHZhcl9jb2hvcnQkdmFyaWFibGUpCmlmIChsZW5ndGgobWlzc2luZykgIT0gMCApewogIG1pc3NpbmdfZGYgPC0gZGF0YS5mcmFtZSh2YXJpYWJsZSA9IG1pc3NpbmcsIHByY3QgPSBOQSwgY29ob3J0X2lkID0gdW5pcXVlKHZhcl9jb2hvcnQkY29ob3J0X2lkKSkKICB2YXJfY29ob3J0IDwtIGJpbmRfcm93cyh2YXJfY29ob3J0LCBhc190aWJibGUobWlzc2luZ19kZikpCn0gZWxzZSBpZiAobGVuZ3RoKG1pc3NpbmcpID09IDApIHsKICBtaXNzaW5nIDwtIHNldGRpZmYodmFyX2NvaG9ydCR2YXJpYWJsZSwgdmFyX3NpbmdsZSR2YXJpYWJsZSkKICBpZiAobGVuZ3RoKG1pc3NpbmcpICE9IDApewogIG1pc3NpbmdfZGYgPC0gZGF0YS5mcmFtZSh2YXJpYWJsZSA9IG1pc3NpbmcsIHByY3QgPSBOQSwgY29ob3J0X2lkID0gdW5pcXVlKHZhcl9zaW5nbGUkY29ob3J0X2lkKSkKICB2YXJfc2luZ2xlIDwtIGJpbmRfcm93cyh2YXJfc2luZ2xlLCBhc190aWJibGUobWlzc2luZ19kZikpCiAgfQp9CgpobV9jb2hvcnQgPC0gZ2dwbG90KHZhcl9jb2hvcnQsIGFlcyh4ID0gdmFyaWFibGUsIHkgPSBjb2hvcnRfaWQsIGZpbGwgPSBwcmN0KSkgKyAKICAgIGdlb21fdGlsZSgpICsgdGhlbWVfY2xhc3NpYygpICsKICAgIHRoZW1lKGF4aXMudGV4dC54PWVsZW1lbnRfYmxhbmsoKSwgYXhpcy50aWNrcy54PWVsZW1lbnRfYmxhbmsoKSwgYXhpcy5saW5lPWVsZW1lbnRfYmxhbmsoKSkrCiAgIHNjYWxlX2ZpbGxfZ3JhZGllbnQobG93ID0gInllbGxvdyIsIGhpZ2g9InJlZCIsIG5hLnZhbHVlID0gImxpZ2h0Z3JheSIsIGxpbWl0cyA9IGMoMCwxMDApKSArCiAgICBsYWJzKHggPSAiIiwgeSA9ICJjb2hvcnQiLCB0aXRsZSA9cGxvdHRpdGxlKSArCiAgICBnZW9tX3RleHQoYWVzKGxhYmVsPXJvdW5kKHByY3QsIDIpKSwgc2l6ZSA9IHRleHRzaXplLCBjb2xvciA9ICJibGFjayIpCgpobV9zaW5nbGUgPC0gZ2dwbG90KHZhcl9zaW5nbGUsIGFlcyh4ID0gdmFyaWFibGUsIHkgPSBjb2hvcnRfaWQsIGZpbGwgPSBwcmN0KSkgKyAKICAgIGdlb21fdGlsZSgpICsgIHRoZW1lX2NsYXNzaWMoKSArCiAgICB0aGVtZShheGlzLnRleHQueD1lbGVtZW50X3RleHQoYW5nbGU9OTAsIGhqdXN0PTEpLCBheGlzLmxpbmU9ZWxlbWVudF9ibGFuaygpKSsKICAgIHNjYWxlX2ZpbGxfZ3JhZGllbnQobG93ID0gInllbGxvdyIsIGhpZ2ggPSAicmVkIiwgbmEudmFsdWUgPSAibGlnaHRncmF5IiwgbGltaXRzID0gYygwLDEwMCkpKyBsYWJzKHkgPSAiY29ob3J0IikgKwogICAgZ2VvbV90ZXh0KGFlcyhsYWJlbD1yb3VuZChwcmN0LCAyKSksIHNpemUgPSB0ZXh0c2l6ZSwgY29sb3IgPSAiYmxhY2siKSAKCnBsb3RfZ3JpZChobV9jb2hvcnQsIGhtX3NpbmdsZSwgYWxpZ24gPSAidiIsIG5yb3cgPSAyLCByZWxfaGVpZ2h0cyA9IGMoMS8yLCAxLzIpKQp9CmBgYAoKIyBTZWFyY2ggc3RyYXRlZ3kKCkVsZWN0cm9uaWMgYmlibGlvZ3JhcGhpY2FsIGRhdGFiYXNlcyB3ZXJlIHNlYXJjaGVkLCBib3RoIGluZGV4ZWQgKFB1Yk1lZCwgRW1iYXNlKSBhbmQgcHJlcHJpbnQgcmVwb3NpdG9yaWVzIChCaW9SeGl2IGFuZCBNZWRSeGl2KS4gQWRkaXRpb25hbGx5LCBDT1ZJRC0xOS1zcGVjaWZpYyByZXNlYXJjaCByZXBvc2l0b3JpZXMgd2VyZSBiZSBzZWFyY2hlZCAoQ29jaHJhbmUgQ09WSUTigJAxOSBTdHVkeSBSZWdpc3RlciwgdGhlIFdvcmxkIEhlYWx0aCBPcmdhbml6YXRpb24gKFdITykgQ09WSUTigJAxOSBHbG9iYWwgUmVzZWFyY2ggRGF0YWJhc2UpLiBQdWJsaWNhdGlvbnMgaW4gRW5nbGlzaCBsYW5ndWFnZSBiZXR3ZWVuIDMxIERlY2VtYmVyIDIwMTkgdXAgdG8gMzAgSnVuZSAyMDIwLCB3aGVuIHRoZSBmaW5hbCBzZWFyY2ggd2FzIGNhcnJpZWQgb3V0LCB3ZXJlIHJldmlld2VkIG9uIGVsaWdpYmlsaXR5LiBCb3RoIGZpbmlzaGVkIGFuZCBvbmdvaW5nIHN0dWRpZXMgd2VyZSBjb25zaWRlcmVkLiBUaGUgcmVmZXJlbmNlIGxpc3RzIG9mIHRoZSBpbmNsdWRlZCBzdHVkaWVzIHdlcmUgY29uc2lkZXJlZCBhcyBhbiBhZGRpdGlvbmFsIHNvdXJjZS4gCgpTZWFyY2ggc3RyYXRlZ3kgZm9jdXNlZCBvbiBrZXl3b3JkcyBpbnZvbHZpbmcgdGhlIGh5cGVyaW5mbGFtbWF0b3J5IHByZXNlbnRhdGlvbiAoUElNUy1UUywgTUlTLUMsIGh5cGVyaW5mbGFtbWF0aW9uLCBITEgsIHRveGljIHNob2NrIHN5bmRyb21lLCB2YXNjdWxpdGlzLCBLYXdhc2FraSBkaXNlYXNlKSwgYXMgd2VsbCBhcyB0aGUgYXNzb2NpYXRpb24gd2l0aCBDT1ZJRC0xOSAoU0FSUy1Db1YtMiwgQ09WSUQtMTksIG5vdmVsIGNvcm9uYXZpcnVzKSBhbmQgdGhlIHBlZGlhdHJpYyBwb3B1bGF0aW9uIChjaGlsZHJlbiwgYWRvbGVzY2VudCwgcGVkaWF0cmljKS4gU3RydWN0dXJlZCBoaWVyYXJjaGljIGtleXdvcmRzIChNZVNILCBFbXRyZWUpIGFuZCB3aWxkY2FyZHMgd2VyZSB1c2VkIHdoZW4gYXBwbGljYWJsZS4gQm9vbGVhbiBvcGVyYXRvcnMgd2VyZSB1c2VkIHRvIGNvbWJpbmUgdGhlIHZhcmlvdXMga2V5d29yZHMgb2YgaW50ZXJlc3QuIEJlbG93LCB0aGUgZnVsbCBzZWFyY2ggdGVybXMgYXJlIHByZXNlbnRlZCBmb3IgdGhlIGRpZmZlcmVudCBkYXRhYmFzZXMpLiAKCiMjIFB1Yk1lZCAKCmBgYAoo4oCcUElNUyrigJ0gT1Ig4oCcTUlTKuKAneKAr09SIOKAnG11bHRpc3lzdGVt4oCvaW5mbGFtbWF0KuKAneKAr09SIOKAnGh5cGVyaW5mbGFtbWF0KuKAnSBPUiDigJxpbmZsYW1tYXRvcnkgZGlzZWFzZeKAnSBPUiDigJxzeXN0ZW1pY+KAr2luZmxhbW1hdCrigJ3igK9PUiDigJxjeXRva2luZSByZWxlYXNl4oCdIE9SIOKAnEthd2FzYWtpKuKAnSBPUiDigJx2YXNjdWxpdGlz4oCdIE9SIOKAnHRveGljIHNob2Nr4oCd4oCvT1Ig4oCcc2hvY2vigJ0gT1IgKCJwZWRpYXRyaWPigK9tdWx0aXN5c3RlbSBpbmZsYW1tYXRvcnkgZGlzZWFzZSwgQ09WSUQtMTkgcmVsYXRlZCIgW1N1cHBsZW1lbnRhcnkgQ29uY2VwdF0pIE9SICJNdWNvY3V0YW5lb3Vz4oCvTHltcGggTm9kZSBTeW5kcm9tZSJbTWVzaF0gT1IgIlNob2NrIltNZXNoXSBPUiAiVmFzY3VsaXRpcyJbTWVzaF0gT1Ig4oCcaW5mbGFtbWF0aW9u4oCdW01lU0hdKeKAr0FOROKAryjigJxjb3ZpZCrigJ0gb3Ig4oCcc2Fycy1jb3YtMuKAnSBvciDigJwyMDE5LW5Db3bigJ0gb3Ig4oCcbm92ZWwgY29yb25hdmlydXPigJ0gb3Ig4oCcY29yb25hdmlydXMgZGlzZWFzZeKAnSBvcuKAryJDT1ZJRC0xOSIgW1N1cHBsZW1lbnRhcnkgQ29uY2VwdF0gT1LigK8ic2V2ZXJlIGFjdXRlIHJlc3BpcmF0b3J5IHN5bmRyb21lIGNvcm9uYXZpcnVzIDIiIFtTdXBwbGVtZW50YXJ5IENvbmNlcHRdKSBBTkTigK8o4oCcY2hpbGQq4oCdIG9yIOKAnGFkb2xlc2NlbirigJ0gb3Ig4oCcdGVlbirigJ0gb3Ig4oCccGVkaWF0cmljKuKAnSBvciDigJxpbmZhbnTigJ0gb3Ig4oCcbmV3Ym9ybuKAnSBvcuKAryJDaGlsZCJbTWVzaF3igK9PUuKAryJBZG9sZXNjZW50IltNZXNoXSBPUuKAryJQZWRpYXRyaWNzIltNZXNoXeKAr29yICJJbmZhbnQs4oCvTmV3Ym9ybiJbTWVzaF3igK9vcuKAryJJbmZhbnQiW01lc2hdKSBBTkQgKCIyMDE5LzEyLzMxIltEYXRlIC0gUHVibGljYXRpb25dIDogIjMwMDAiW0RhdGUgLSBQdWJsaWNhdGlvbl0p4oCvIApgYGAKCiMjIEVtYmFzZSAgCgpgYGAKKCdwaW1zKicgT1IgJ21pcyfigK9PUiDigJhtaXMtY+KAmeKAr09SICdtdWx0aXN5c3RlbeKAr2luZmxhbW1hdConIE9SICdoeXBlcmluZmxhbW1hdConIE9SICdpbmZsYW1tYXRvcnkgZGlzZWFzZScgT1IgJ3N5c3RlbWlj4oCvaW5mbGFtbWF0KicgT1IgJ2N5dG9raW5lIHJlbGVhc2UnIE9SICdrYXdhc2FraSonIE9SICd2YXNjdWxpdGlzJyBPUiAndG94aWMgc2hvY2snIE9SICdzaG9jaycpIEFORCAoJ2NvdmlkKicgT1IgJ3NhcnMtY292LTInIE9SICcyMDE5LW5jb3YnIE9SICdub3ZlbCBjb3JvbmF2aXJ1cycgT1IgJ2Nvcm9uYXZpcnVzIGRpc2Vhc2UnKSBBTkQgKCdjaGlsZConIE9SICdhZG9sZXNjZW4qJyBPUiAndGVlbionIE9SICdwZWRpYXRyaWMqJyBPUiAnaW5mYW50JyBPUiAnbmV3Ym9ybicpIEFORCBbMzEtMTItMjAxOV0vc2TigK8gCmBgYAoKIyMgQmlvUnhpdiBhbmQgTWVkUnhpdiAKTGl0ZXJhdHVyZSBzZWFyY2ggaW4gYmlvcnhpdiBhbmQgbWVkcnhpdiB3YXMgZG9uZSB3aXRoIHRoZSBSIGJ5IGRvd25sb2FkaW5nIHRoZSBkYXRhIGZyb20gdGhlIGRlZGljYXRlZCBbQ09WSUQtMTkgU0FSUy1Db1YtMiBwcmVwcmludHMgcGFnZV0oaHR0cHM6Ly9jb25uZWN0LmJpb3J4aXYub3JnL3JlbGF0ZS9jb250ZW50LzE4MSkgaW4ganNvbiBmb3JtYXQsIGFuZCBjYW4gYmUgZm91bmQgb24gW0dpdGh1Yl0oaHR0cHM6Ly9naXRodWIuY29tL3JtdnBhZW1lL1BJTVNfVFMvYmxvYi9tYXN0ZXIvcHJlcHJpbnRfc2VhcmNoLlIpLgoKCiMjIENvY2hyYW5lIENPVklELTE5IHN0dWR5IHJlZ2lzdGVyIAoKYGBgCihwaW1zKiBPUiBtaXMgT1IgIm1pcy1jIiBPUiAibXVsdGlzeXN0ZW0gaW5mbGFtbWF0KiIgT1IgaHlwZXJpbmZsYW1tYXQqIE9SICJpbmZsYW1tYXRvcnkgZGlzZWFzZSIgT1IgInN5c3RlbWljIGluZmxhbW1hdCoiIE9SICJjeXRva2luZSByZWxlYXNlIiBPUiBrYXdhc2FraSogT1IgdmFzY3VsaXRpcyBPUiAidG94aWMgc2hvY2siIE9SIHNob2NrKSBBTkQgKGNoaWxkKiBPUiBhZG9sZXNjZW4qIE9SIHRlZW4qIE9SIHBlZGlhdHJpYyogT1IgaW5mYW50IE9SIG5ld2Jvcm4pIApgYGAKCiMjIFdITyBDT1ZJRC0xOSBHbG9iYWwgbGl0ZXJhdHVyZSBvbiBjb3JvbmF2aXJ1cyBkaXNlYXNlIAoKYGBgCigicGltcyoiIE9SICJtaXMiIE9SICJtaXMtYyIgT1IgIm11bHRpc3lzdGVt4oCvaW5mbGFtbWF0KiIgT1IgImh5cGVyaW5mbGFtbWF0KiIgT1IgImluZmxhbW1hdG9yeSBkaXNlYXNlIiBPUiAic3lzdGVtaWPigK9pbmZsYW1tYXQqIiBPUiAiY3l0b2tpbmUgcmVsZWFzZSIgT1IgImthd2FzYWtpKiIgT1IgInZhc2N1bGl0aXMiIE9SICJ0b3hpYyBzaG9jayIgT1IgInNob2NrIikgQU5EICgiY2hpbGQqIiBPUiAiYWRvbGVzY2VuKiIgT1IgInRlZW4qIiBPUiAicGVkaWF0cmljKiIgT1IgImluZmFudCIgT1IgIm5ld2Jvcm4iKSAKYGBgCgojIFN0dWR5IHNlbGVjdGlvbiBhbmQgcmlzayBvZiBiaWFzIGFzc2Vzc21lbnQKT3JpZ2luYWwgc3R1ZGllcyB3ZXJlIGluY2x1ZGVkIHdpdGggZm9sbG93aW5nIGRlc2lnbnM6IFJDVCwgb2JzZXJ2YXRpb25hbCBzdHVkaWVzLCBjYXNlLWNvbnRyb2wgc3R1ZGllcywgY3Jvc3Mtc2VjdGlvbmFsIHN0dWRpZXMsIGNhc2UgcmVwb3J0cyBhbmQgY2FzZSBzZXJpZXMuIAoKUmVjb3JkcyBlbGlnaWJsZSBmb3IgaW5jbHVzaW9uIHNob3VsZCBwcmVzZW50IGNsaW5pY2FsIGNhc2VzIGZ1bGZpbGxpbmcgdGhlIGZvbGxvd2luZyAzIGNyaXRlcmlhOiAKCkluY2x1c2lvbiBjcml0ZXJpYQoKMS4JU3R1ZHkgcG9wdWxhdGlvbjogaHlwZXJpbmZsYW1tYXRvcnkgc3luZHJvbWUgbWVldGluZyB0aGUgY2FzZSBkZWZpbml0aW9ucyBvZiBQSU1TLVRTIG9yIE1JUygtQykgaW4gY2hpbGRyZW4gKDAtMTkgeWVhcnMgb2YgYWdlKSB3aXRoIGEgdGVtcG9yYWwgYXNzb2NpYXRpb24gd2l0aCBjb25maXJtZWQgb3IgcHJvYmFibGUgQ09WSUQtMTkKMi4JT3V0Y29tZTogY2xpbmljYWwsIGVwaWRlbWlvbG9naWNhbCBhbmQgaW1tdW5vbG9naWNhbCBkZXNjcmlwdGlvbnMsIHRoZXJhcGV1dGljIG1hbmFnZW1lbnQgYW5kIGNsaW5pY2FsIGVmZmVjdCwgYW5kIHByb2dub3NpcyBvZiBpbmRpdmlkdWFscyBvciBjb2hvcnRzIG9mIHBhdGllbnRzLgozLglUeXBlcyBvZiBzdHVkeSBkZXNpZ25zOiBSQ1QsIG9ic2VydmF0aW9uYWwgc3R1ZGllcywgY2FzZS1jb250cm9sIHN0dWRpZXMsIGNyb3NzLXNlY3Rpb25hbCBzdHVkaWVzLCBjYXNlIHJlcG9ydHMgYW5kIGNhc2Ugc2VyaWVzCgpFeGNsdXNpb24gY3JpdGVyaWEKMS4JU3R1ZGllcyBvbiBhZHVsdCBwYXRpZW50cyB3aXRoIFNBUlMtQ29WLTIgaW5mZWN0aW9uIGFuZC9vciBTQVJTLUNvVi0yIGFzc29jaWF0ZWQgaHlwZXJpbmZsYW1tYXRvcnkgc3luZHJvbWVzCjIuCVN0dWRpZXMgb24gcGVkaWF0cmljIHBhdGllbnRzIHdpdGggb3RoZXIgY29yb25hdmlydXMgaW5mZWN0aW9ucyAoU0FSUy1Db1YtMSBhbmQgTWlkZGxlIEVhc3QgUmVzcGlyYXRvcnkgU3luZHJvbWUgQ29yb25hdmlydXMgKE1FUlMtQ29WKSBpbmZlY3Rpb24gb3Igb3RoZXIgcmVzcGlyYXRvcnkgaW5mZWN0aW9ucy4KMy4JU3R1ZGllcyB3aXRoIGluY29tcGxldGUgb3IgbGFja2luZyBuZWNlc3NhcnkgZGF0YSAKNC4JRHVwbGljYXRlIHN0dWRpZXMKNS4JU3R1ZGllcyB3aXRob3V0IGFjY2Vzc2libGUgZnVsbCB0ZXh0IHZlcnNpb25zCjYuCVN0dWRpZXMgbm90IGluIEVuZ2xpc2ggbGFuZ3VhZ2UKClN0dWR5IHNlbGVjdGlvbiB3YXMgYSB0d28tc3RhZ2UgcHJvY2VzcyB3aXRoLCBmaXJzdCwgdGl0bGVzIGFuZCBhYnN0cmFjdHMgb2Ygc3R1ZGllcyBzY3JlZW5lZCB3aXRoIHJldHJpZXZhbCB1c2luZyB0aGUgc2VhcmNoIHN0cmF0ZWd5IGFuZCB0aGVuLCBzZWNvbmQsIGZ1bGwgdGV4dCBzY3JlZW5pbmcgb2YgcG90ZW50aWFsbHkgZWxpZ2libGUgc3R1ZGllcyBhc3Nlc3NlZCBieSB0d28gcmV2aWV3ZXJzIGluZGVwZW5kZW50bHkuIEFueSBkaXNhZ3JlZW1lbnQgb3ZlciB0aGUgZWxpZ2liaWxpdHkgb2YgcGFydGljdWxhciBzdHVkaWVzIHdhcyByZXNvbHZlZCB0aHJvdWdoIGRpc2N1c3Npb24gd2l0aCBhIHRoaXJkIHJldmlld2VyLiAKClRoZSBQcmVmZXJyZWQgUmVwb3J0aW5nIEl0ZW1zIGZvciBTeXN0ZW1hdGljIFJldmlld3MgYW5kIE1ldGEtQW5hbHlzZXMgKFBSSVNNQSkgY2hlY2tsaXN0IHdhcyB1c2VkIHRvIGd1aWRlIHRoZSBzdHVkeSBzZWxlY3Rpb24gYW5kIGV4dHJhY3Rpb24gcHJvY2Vzcy4gUmlzayBmb3IgYmlhcyBvbiBlbGlnaWJsZSBvYnNlcnZhdGlvbmFsIHN0dWRpZXMgd2VyZSBhc3Nlc3NlZCBieSBMSCBhY2NvcmRpbmcgdG8gdGhlIE5ld0Nhc3RsZS1PdHRhd2EgU2NhbGUgKE5PUyksIHdpdGggZnVsbCB2ZXJpZmljYXRpb24gb2YgYWxsIGp1ZGdtZW50cyBieSBSVlAuIExldmVsIG9mIGV2aWRlbmNlIHdhcyByYXRlZCBhY2NvcmRpbmcgdG8gU2Fja2V0dC4KCgojIFBSSVNNQSBmbG93IGRpYWdyYW0KCiFbXSguL3Bsb3RzL1BSSVNNQSAyMDA5IGZsb3cgZGlhZ3JhbS5wbmcpCgojIERhdGEgZXh0cmFjdGlvbgpBbGwgb3JpZ2luYWwgc3R1ZGllcyBkZXNjcmliaW5nIGNsaW5pY2Fs4oCvY2FzZXPigK9tZWV0aW5nIHRoZSBjYXNlIGRlZmluaXRpb27igK9vZiBQSU1TLVRTLOKAr2FzIGRlZmluZWQgYnkgUkNQQ0gs4oCvd2VyZSBlbGlnaWJsZSBmb3IgaW5jbHVzaW9uLiBQcmltYXJ5IG91dGNvbWUgYW5hbHlzaXMgZm9jdXNlZCBvbiBjbGluaWNhbCwgZXBpZGVtaW9sb2dpY2FsIGFuZCBpbW11bm9sb2dpY2FsIG1hbmlmZXN0YXRpb25zLCB0aGVyYXBldXRpYyBtYW5hZ2VtZW50IGFuZOKAr3Byb2dub3Npcy7igK8gCgpUaGUgZm9sbG93aW5nIGRhdGEgcG9pbnRzIHdlcmUgb3V0bGluZWQgdG8gYmUgZXh0cmFjdGVkIG91dCBvZiBlbGlnaWJsZSByZWNvcmRzOiBwYXRpZW50IGNoYXJhY3RlcmlzdGljcyAoZS5nLiBzZXgsIGFnZSwgZXRobmljaXR5LCBhbnRocm9wb21ldHJ5LOKApiksIGNvbW9yYmlkaXRpZXMgKGUuZy4gY2FyZGlvdmFzY3VsYXIgZGlzZWFzZSwgcmVzcGlyYXRvcnkgZGlzZWFzZSwgZGlhYmV0ZXMgbWVsbGl0dXMsIHJlbmFsIGRpc2Vhc2UsIG1hbGlnbmFuY3kvY2FuY2VyLCBpbW11bm9kZWZpY2llbmN5LOKApiksIFNBUlMtQ29WLTIgaW5mZWN0aW9uIHJlbGF0ZWQgZGF0YSAoZS5nLiBjbG9zZSBjb250YWN0cyB3aXRoIGNvbmZpcm1lZCBvciBzdXNwZWN0ZWQgQ09WSUQtMTksIFBDUiBhbmQgc2Vyb2xvZ3kgcmVzdWx0cyzigKYpLCBjbGluaWNhbCBzeW1wdG9tcyAoZS5nLiBmZXZlciwgcmVzcGlyYXRvcnksIGdhc3Ryby1pbnRlc3RpbmFsLCBuZXVyb2xvZ2ljYWwsIGRlcm1hdG9sb2dpY2FsLCByZW5hbCBvciBjYXJkaWFjIG1hbmlmZXN0YXRpb25zLCBkZXNjcmlwdGlvbiBvZiBLYXdhc2FraSBjcml0ZXJpYSzigKYpLCBsYWJvcmF0b3J5IHRlc3RzIGF0IHZhcmlvdXMgdGltZSBwb2ludHMgKGUuZy4gaGFlbW9nbG9iaW4sIFdCQywgbHltcGhvY3l0ZSwgbmV1dHJvcGhpbCBhbmQgcGxhdGVsZXQgY291bnRzLCBzb2RpdW0sIGZlcnJpdGluLCBELWRpbWVyLCBmaWJyaW5vZ2VuLCBhbGJ1bWluLCBjcmVhdGluaW5lLCBsaXZlciB0cmFuc2FtaW5hc2VzLCBDSywgTERILCB0cm9wb25pbiwgTlQtcHJvQk5QLCBDUlAsIEVTUiwgc2VydW0gY3l0b2tpbmVzLCBjb21wbGVtZW50LCBpbW11bm9nbG9idWxpbnMs4oCmKSwgcmFkaW9sb2dpY2FsIHJlc3VsdHMsIGhvc3BpdGFsIGFkbWlzc2lvbiBkYXRhIChkYXlzIG9mIGhvc3BpdGFsaXNhdGlvbiwgZGF5cyBvZiBJQ1UgY2FyZSzigKYpLCBjcml0aWNhbCBjYXJlIGludGVydmVudGlvbnMgKGludmFzaXZlIGFuZCBub24taW52YXNpdmUgdmVudGlsYXRpb24sIGlub3Ryb3Blcy92YXNvcHJlc3NvcnMgdXNlLCBFQ01PLOKApikgYW5kIHRoZXJhcGV1dGljcyBhbmQgdGhlaXIgZWZmZWN0IChjb3J0aWNvc3Rlcm9pZHMsIGFzcGlyaW4sIElWSUcsIGJpb3RoZXJhcGV1dGljcywgYW50aWJpb3RpY3Ms4oCmKS4gRmllbGRzIHdpdGggaW5zdWZmaWNpZW50IGRhdGEgd2lsbCBiZSBleGNsdWRlZCBmcm9tIGZpbmFsIGFuYWx5c2lzLiBBZGRpdGlvbmFsIHBhcmFtZXRlcnMgd2VyZSBpbmNsdWRlZCBpZiByZWxldmFudC4gCgoKQ2FzZXMgd2VyZSBleGNsdWRlZCBpZiBpbnN1ZmZpY2llbnQgZGF0YSBzdWdnZXN0aW5nIGEgdGVtcG9yYWwgYXNzb2NpYXRpb24gd2l0aCBTQVJTLUNvVi0yIHdhcyBwcmVzZW50ZWQuIEEgcmVjZW50IG9yIGN1cnJlbnQgcG9zaXRpdmUgU0FSUy1Db1YtMiBQQ1IgKG5hc29waGFyeW5nZWFsLCBmZWNhbCwgb3RoZXIpIG9yIHNlcm9sb2d5IChJZ0EsIElnTSwgSWdHKSByZXN1bHRzIG5lZWRlZCB0byBiZSBwcmVzZW50ZWQsIG9yIGhpc3Rvcnkgb2YgY2xvc2UgY29udGFjdCAoZS5nLiBob3VzZWhvbGQpIHdpdGggYSBjb25maXJtZWQgb3IgaGlnaGx5IHN1c3BlY3QgY2FzZSBvZiBDT1ZJRC0xOSB3YXMgcmVxdWlyZWQuIFN0dWRpZXMgd2VyZSBleGNsdWRlZCBpZiBkYXRhIHdhcyBpbmNvbnNpc3RlbnRseSBwcmVzZW50ZWQuIAoKCkFzIGEgc2Vjb25kYXJ5IG91dGNvbWUsIGl0IHdhcyBvdXRsaW5lZCB0byBtYWtlIGEgcXVhbGl0YXRpdmUgYXNzZXNzbWVudCBhbmQgcHJvcG9zZSBhbiBpbW11bm9sb2dpY2FsIG1lY2hhbmlzbSB1bmRlcnBpbm5pbmcgdGhpcyBpbmZsYW1tYXRvcnkgc3luZHJvbWUgYmFzZWQgb24gdGhlIGNhc2VzIHJlcG9ydGVkIGluIGxpdGVyYXR1cmUgYW5kL29yIGltbXVub2xvZ2ljYWwgaW52ZXN0aWdhdGlvbnMgcGVyZm9ybWVkIGluIHRoZXNlIGFmZmVjdGVkIGNoaWxkcmVuLiBOZXZlcnRoZWxlc3MsIHVwIHRvIHRoZSBmaW5hbCBzZWFyY2gsIGluc3VmZmljaWVudCBkYXRhIHdhcyBhdmFpbGFibGUgdG8gY29uZHVjdCBzdWNoIGFzc2Vzc21lbnRzLiAgCgpBIHNpbmdsZSByZXZpZXdlciAoTEgpIGV4dHJhY3RlZCBkYXRhIHVzaW5nIGEgc3RhbmRhcmRpemVkIGZvcm0sIHdoaWxlIGEgc2Vjb25kIHJldmlld2VyIChSVlApIGNyb3NzIGNoZWNrZWQgYWxsIGRhdGEgZm9yIGNvcnJlY3RuZXNzIGFuZCBjb21wbGV0ZW5lc3MuIEFueSBkaXNhZ3JlZW1lbnQgb3ZlciBzdHVkeSBlbGlnaWJpbGl0eSBhbmQgY29uZmxpY3Qgb24gZGF0YSBleHRyYWN0aW9uIHdlcmUgcmVzb2x2ZWQgYnkgYSB0aGlyZCByZXZpZXdlciAoRkgpLiAKCkNvaG9ydCBzdHVkaWVzIGFuZCBzdHVkaWVzIHJlcG9ydGluZyBvbiBzaW5nbGUgY2FzZXMgd2VyZSBhbmFseXNlZCBzZXBhcmF0ZWx5LCBhcyB3ZSBkaWQgbm90IGhhdmUgYWNjZXNzIHRvIHRoZSBpbmRpdmlkdWFsIGNhc2UgY2hhcmFjdGVyaXN0aWNzIG9mIHRoZSBjb2hvcnQgc3R1ZGllcy4gIEZvciB0aGUgY29ob3J0IHN0dWRpZXMsIHByb3BvcnRpb25zIHdlcmUgY2FsY3VsYXRlZCBieSBzdW1taW5nIG9ubHkgdGhlIHN0dWRpZXMgd2hpY2ggcmVwb3J0IG9uIHRoZSB2YXJpYWJsZSwgZXhjZXB0IGZvciByYXJlIGNvbmRpdGlvbnMgc3VjaCBhcyBkZWF0aCwgY29tb3JiaWRpdGllcywgdXNlIG9mIEVDTU8gb3IgYmlvcGhhcm1hY2V1dGljYWxzLgoKIyBEYXRhIGltcG9ydCBhbmQgY2xlYW5pbmcKIyMgU2luZ2xlIGNhc2VzCkFmdGVyIGRhdGEgY29sbGVjdGlvbiwgd2UgaW1wb3J0IHRoZSBzaW5nbGUgY2FzZXMgZnJvbSB0aGUgW2dlbmVyYWwgZXhjZWwgc2hlZXRdKCkgYW5kIHRyYW5zZm9ybSB0aGUgZXhjZWwgc2hlZXQgc28gdGhhdCB2YXJpYWJsZXMgYXJlIGNvbHVtbnMgYW5kIHJvd3MgYXJlIGNhc2VzLiBDb2x1bW5zIHdpdGhvdXQgYW55IHZhbHVlcyBhcmUgYWxzbyByZW1vdmVkLiAKClRoZSBzaW5nbGUgY2FzZXMgZnJvbSBQb3VsZXR0eSAoMTAuMTEzNi9hbm5yaGV1bWRpcy0yMDIwLTIxNzk2MCkgYXJlIGV4Y2x1ZGVkIChhcyB0aGV5IGFyZSBpbmNsdWRlZCBpbiB0aGUgY29ob3J0cykuCgoKYGBge3J9CmRmX3NpbmdsZWNhc2VzIDwtCiAgcmVhZF9leGNlbCgiL1VzZXJzL3JtdnBhZW1lL09uZWRyaXZlL1VHZW50L1BJTVMtVFMgU3lzdGVtYXRpYyBSZXZpZXcgLSBHZW5lcmFsL0RhdGEgZXh0cmFjdGllL2RhdGEgZXh0cmFjdGllLnhsc3giLAogICAgICAgICAgICAgc2hlZXQgPSAiU2luZ2xlIGNhc2VzIiwKICAgICAgICAgICAgIHNraXAgPSAxLAogICAgICAgICAgICAgY29sX25hbWVzID0gRkFMU0UpWywtYygxOjIpXQpkZl9zaW5nbGVjYXNlcyA8LSBkZl9zaW5nbGVjYXNlcyAlPiUgdCgpCmRmX3NpbmdsZWNhc2VzIDwtIGFzLmRhdGEuZnJhbWUoZGZfc2luZ2xlY2FzZXMsIHN0cmluZ3NBc0ZhY3RvcnMgPSBGQUxTRSkKbm1zIDwtIGFzLnZlY3RvcihkZl9zaW5nbGVjYXNlc1sxLF0pCm5tc1tpcy5uYShubXMpXSA8LSAndG1wJwpjb2xuYW1lcyhkZl9zaW5nbGVjYXNlcykgPC0gbWFrZS51bmlxdWUoYXMuY2hhcmFjdGVyKG5tcykpCmRmX3NpbmdsZWNhc2VzIDwtIGRmX3NpbmdsZWNhc2VzWy0xLF0KZGZfc2luZ2xlY2FzZXMgPC0gZGZfc2luZ2xlY2FzZXMgJT4lIHNlbGVjdCgtY29udGFpbnMoInRtcCIpKQpkZl9zaW5nbGVjYXNlcyA8LSBkZl9zaW5nbGVjYXNlcyAlPiUgc2VsZWN0KC12YXJpYWJsZV9pZCkKCmRmX3NpbmdsZWNhc2VzIDwtIGRmX3NpbmdsZWNhc2VzICU+JSAKICBtdXRhdGVfYWxsKGZ1bnMoc3RyX3JlcGxhY2UoLiwgIlllcyIsICJ5ZXMiKSkpCmRmX3NpbmdsZWNhc2VzIDwtIGRmX3NpbmdsZWNhc2VzICU+JSAKICBtdXRhdGVfYWxsKGZ1bnMoc3RyX3JlcGxhY2UoLiwgIk5vIiwgIm5vIikpKQpkZl9zaW5nbGVjYXNlcyA8LSBkZl9zaW5nbGVjYXNlcyAlPiUgCiAgbXV0YXRlX2FsbChmdW5zKHN0cl9yZXBsYWNlKC4sICJwb3MiLCAieWVzIikpKQpkZl9zaW5nbGVjYXNlcyA8LSBkZl9zaW5nbGVjYXNlcyAlPiUgCiAgbXV0YXRlX2FsbChmdW5zKHN0cl9yZXBsYWNlKC4sICJuZWciLCAibm8iKSkpCgpkZl9zaW5nbGVjYXNlcyA8LSBkZl9zaW5nbGVjYXNlcyAlPiUKICByZXBsYWNlX3dpdGhfbmFfYWxsKGNvbmRpdGlvbiA9IH4ueCA9PSAiTkEiKQoKZGZfc2luZ2xlY2FzZXMgPC0gdHlwZV9jb252ZXJ0KGRmX3NpbmdsZWNhc2VzKQpkZl9zaW5nbGVjYXNlc19pbmNsUG91bGV0dHkgPC0gZGZfc2luZ2xlY2FzZXMKZGZfc2luZ2xlY2FzZXMgPC0gZGZfc2luZ2xlY2FzZXMgJT4lIGZpbHRlcihkb2kgIT0gImh0dHBzOi8vMTAuMTEzNi9hbm5yaGV1bWRpcy0yMDIwLTIxNzk2MCIpICAjIHRoZXNlIGNhc2VzIGFyZSBleGNsdWRlZCBhY2NvcmRpbmcgdG8gdGhlIGRhdGEgc2hlZXQKCmRmX3NpbmdsZWNhc2VzIDwtIGRmX3NpbmdsZWNhc2VzW2NvbFN1bXMoIWlzLm5hKGRmX3NpbmdsZWNhc2VzKSkgPiAwXQoKZGZfc2luZ2xlY2FzZXMkZGF0ZV9vZl9wdWJsaWNhdGlvbiA8LSBhcy5EYXRlKGRmX3NpbmdsZWNhc2VzJGRhdGVfb2ZfcHVibGljYXRpb24sIG9yaWdpbiA9ICIxODk5LTEyLTMwIikKCm5fc2luZ2xlX2Nhc2VzIDwtIG5yb3coZGZfc2luZ2xlY2FzZXMpCgoKYGBgCgoKIyMjIE1ha2luZyBzdW1tYXJ5IHN0YXRpc3RpY3MKCkluIHRoaXMgc2VjdGlvbiwgZGF0YSBpcyBzdW1tYXJpemVkLiBGb3IgZXhhbXBsZSwgaWYgdGhlcmUgYXJlIGFueSBjb21vcmJpZGl0aWVzIHByZXNlbnQsIGEgY29sdW1uICJjb21vcmJfYW55IiBpcyBhZGRlZCBhbmQgYW5ub3RhdGVkIGFzIFRSVUUuIFRoZSBzYW1lIGlzIGRvbmUgZm9yIENPVklEIHNlcm9sb2d5IGFuZCBzeW1wdG9tcyBvZiBtYWpvciBvcmdhbiAocmVzcGlyYXRvcnksIGNhcmRpb3Zhc2N1bGFyIGV0YykuCgpgYGB7cn0KZGZfc2luZ2xlY2FzZXMgPC0gZGZfc2luZ2xlY2FzZXMgJT4lIG11dGF0ZShjb21vcmJfYW55ID0gYXBwbHkoZGZfc2luZ2xlY2FzZXMgJT4lIHNlbGVjdChjb250YWlucygiY29tb3JiIikpLCAxLCBhbnkpKQpkZl9zaW5nbGVjYXNlcyA8LSBkZl9zaW5nbGVjYXNlcyAlPiUgbW92ZW1lKC4sICJjb21vcmJfYW55IGJlZm9yZSBjb21vcmJfY2FyZGlvdmFzYyIpCmBgYAoKSWYgSWdHLCBJZ0EsIElnTSBvciBDT1ZJRCBzZXJvbG9neSBpcyByZXBvcnRlZCBhcyBwb3NpdGl2ZSwgdGhlIGNvbHVtbiBjb3ZpZF9zZXJvX2FueSBpcyBhbm5vdGF0ZWQgYXMgVFJVRS4KCmBgYHtyfQpkZl9zaW5nbGVjYXNlcyA8LSBkZl9zaW5nbGVjYXNlcyAlPiUgbXV0YXRlKGNvdmlkX3Nlcm9fYW55ID0gYXBwbHkoZGZfc2luZ2xlY2FzZXMgJT4lIHNlbGVjdChjb3ZpZF9zZXJvX3BvcywgY292aWRfSWdBX3BvcywgY292aWRfSWdNX3BvcywgY292aWRfSWdHX3BvcyksIDEsIGFueSkpCgpkZl9zaW5nbGVjYXNlcyA8LSBkZl9zaW5nbGVjYXNlcyAlPiUgbW92ZW1lKC4sICJjb3ZpZF9zZXJvX2FueSBiZWZvcmUgY292aWRfc2Vyb19wb3MiKQpgYGAKCklmIFBDUissIHN0b29sIFBDUissIElnRywgSWdBLCBJZ00gb3IgQ09WSUQgc2Vyb2xvZ3kgaXMgcmVwb3J0ZWQgYXMgcG9zaXRpdmUsIHRoZSBjb2x1bW4gY292aWRfcG9zX2FueSBpcyBhbm5vdGF0ZWQgYXMgVFJVRS4KCmBgYHtyfQpkZl9zaW5nbGVjYXNlcyA8LSBkZl9zaW5nbGVjYXNlcyAlPiUgbXV0YXRlKGNvdmlkX3Bvc19hbnkgPSBhcHBseShkZl9zaW5nbGVjYXNlcyAlPiUgc2VsZWN0KGNvdmlkX1BDUl9wb3MsIGNvdmlkX1BDUl9zdG9vbF9wb3MsIGNvdmlkX3Nlcm9fcG9zLCBjb3ZpZF9JZ0FfcG9zLCBjb3ZpZF9JZ01fcG9zLCBjb3ZpZF9JZ0dfcG9zKSwgMSwgYW55KSkKCmRmX3NpbmdsZWNhc2VzIDwtIGRmX3NpbmdsZWNhc2VzICU+JSBtb3ZlbWUoLiwgImNvdmlkX3Bvc19hbnkgYmVmb3JlIGNvdmlkX3Nlcm9fYW55IikKYGBgCgpJZiBhbnkgcmVzcGlyYXRvcnkgc3ltcHRvbXMsIHN5bXBfcmVzcF9hbnkgaXMgYW5ub3RhdGVkIGFzIFRSVUUuCgpgYGB7cn0KZGZfc2luZ2xlY2FzZXMgPC0gZGZfc2luZ2xlY2FzZXMgJT4lIG11dGF0ZShzeW1wX3Jlc3BfYW55ID0gYXBwbHkoZGZfc2luZ2xlY2FzZXMgJT4lIHNlbGVjdChzeW1wX3Jlc3BfTlMsIHN5bXBfcmVzcF9VUlQsIHN5bXBfcmVzcF9keXNwbmVhLCBzeW1wX3Jlc3BfcG5ldW1vbmlhLCBzeW1wX3Jlc3BfZmFpbHVyZSwgc3ltcF9yZXNwX2NoZXN0cGFpbiksIDEsIGFueSkpCgpkZl9zaW5nbGVjYXNlcyA8LSBkZl9zaW5nbGVjYXNlcyAlPiUgbW92ZW1lKC4sICJzeW1wX3Jlc3BfYW55IGJlZm9yZSBzeW1wX3Jlc3BfTlMiKQpgYGAKCklmIGFueSBHSSBzeW1wdG9tcywgc3ltcF9HSV9hbnkgaXMgYW5ub3RhdGVkIGFzIFRSVUUuCgpgYGB7cn0KZGZfc2luZ2xlY2FzZXMgPC0gZGZfc2luZ2xlY2FzZXMgJT4lIG11dGF0ZShzeW1wX0dJX2FueSA9IGFwcGx5KGRmX3NpbmdsZWNhc2VzICU+JSBzZWxlY3QoY29udGFpbnMoInN5bXBfR0kiKSksIDEsIGFueSkpCgpkZl9zaW5nbGVjYXNlcyA8LSBkZl9zaW5nbGVjYXNlcyAlPiUgbW92ZW1lKC4sICJzeW1wX0dJX2FueSBiZWZvcmUgc3ltcF9HSV9OUyIpCmBgYAoKSWYgYW55IG5ldXJvbG9naWNhbCBzeW1wdG9tcywgc3ltcF9uZXVyb19hbnkgaXMgYW5ub3RhdGVkIGFzIFRSVUUuCgpgYGB7cn0KZGZfc2luZ2xlY2FzZXMgPC0gZGZfc2luZ2xlY2FzZXMgJT4lIG11dGF0ZShzeW1wX25ldXJvX2FueSA9IGFwcGx5KGRmX3NpbmdsZWNhc2VzICU+JSBzZWxlY3Qoc3ltcF9uZXVyb19oZWFkYWNoZSxzeW1wX25ldXJvX21lbmluZ2l0aXMsc3ltcF9uZXVyb19tZW5pbmdpc20sc3ltcF9uZXVyb19hc3RoZW5pYSxzeW1wX25ldXJvX2lycml0YWIpLCAxLCBhbnkpKQoKZGZfc2luZ2xlY2FzZXMgPC0gZGZfc2luZ2xlY2FzZXMgJT4lIG1vdmVtZSguLCAic3ltcF9uZXVyb19hbnkgYmVmb3JlIHN5bXBfbmV1cm9fR0NTIikKYGBgCgpJZiBhbnkgcmVuYWwgc3ltcHRvbXMsIHN5bXBfcmVuYWxfYW55IGlzIGFubm90YXRlZCBhcyBUUlVFLgoKYGBge3J9CmRmX3NpbmdsZWNhc2VzIDwtIGRmX3NpbmdsZWNhc2VzICU+JSBtdXRhdGUoc3ltcF9yZW5hbF9hbnkgPSBhcHBseShkZl9zaW5nbGVjYXNlcyAlPiUgc2VsZWN0KHN5bXBfcmVuYWxfQUtJKSwgMSwgYW55KSkKCmRmX3NpbmdsZWNhc2VzIDwtIGRmX3NpbmdsZWNhc2VzICU+JSBtb3ZlbWUoLiwgInN5bXBfcmVuYWxfYW55IGJlZm9yZSBzeW1wX3JlbmFsX0FLSSIpCmBgYAoKSWYgYW55IGNhcmRpb3Zhc2N1bGFyIHN5bXB0b21zLCBzeW1wX2NhcmRpb3Zhc2NfYW55IGlzIGFubm90YXRlZCBhcyBUUlVFLgoKYGBge3J9CmRmX3NpbmdsZWNhc2VzIDwtIGRmX3NpbmdsZWNhc2VzICU+JSBtdXRhdGUoc3ltcF9jYXJkaW92YXNjX2FueSA9IGFwcGx5KGRmX3NpbmdsZWNhc2VzICU+JSBzZWxlY3Qoc3ltcF9jYXJkaW92YXNjX215b2NhcmQsCnN5bXBfY2FyZGlvdmFzY19wZXJpY2FyZCwKc3ltcF9jYXJkaW92YXNjX2NvcmRpbGF0LApzeW1wX2NhcmRpb3Zhc2NfYW5ldXJ5c20sCnN5bXBfY2FyZGlvdmFzY19zaG9jaywKc3ltcF9jYXJkaW92YXNjX3RhY2h5Y2FyZCwKc3ltcF9jYXJkaW92YXNjX2Fycmh5dCksIDEsIGFueSkpCgpkZl9zaW5nbGVjYXNlcyA8LSBkZl9zaW5nbGVjYXNlcyAlPiUgbW92ZW1lKC4sICJzeW1wX2NhcmRpb3Zhc2NfYW55IGJlZm9yZSBzeW1wX2NhcmRpb3Zhc2NfbXlvY2FyZCIpCgp3cml0ZS5jc3YoZGZfc2luZ2xlY2FzZXMsIHBhc3RlMCgiLi9kYXRhL2RmX3NpbmdsZWNhc2VzLmNzdiIpKQoKI2RhdGF0YWJsZShkZl9zaW5nbGVjYXNlcywgY2FwdGlvbiA9ICJTaW5nbGUgY2FzZXMgZGF0YWZyYW1lIikKYGBgCgoKPGJ1dHRvbiBvbmNsaWNrPSJsb2NhdGlvbi5ocmVmPSdodHRwczovL2dpdGh1Yi5jb20vcm12cGFlbWUvUElNU19UUy9ibG9iL21hc3Rlci9kYXRhL2RmX3NpbmdsZWNhc2VzLmNzdiciIHR5cGU9ImJ1dHRvbiI+CiAgICAgICAgIERvd25sb2FkIHNpbmdsZSBjYXNlIGRhdGEgYXMgLmNzdiBvbiBHaXRodWI8L2J1dHRvbj4KICAgICAgICAgCiMjIENvaG9ydHMKQWZ0ZXJ3YXJkcywgd2UgZG8gdGhlIHNhbWUgZm9yIHRoZSBjb2hvcnQgc2hlZXQuCgpUaGUgcGFwZXJzIGJ5IEdyaW1hdWQgZXQgYWwuIGFuZCBWZXJkb25pIGV0IGFsLiBhcmUgcmVtb3ZlZCBmcm9tIHRoZSBjb2hvcnQgZGF0YWZyYW1lLCBhcyBtb3N0IGluZm9ybWF0aW9uIGlzIHByZXNlbnQgaW4gdGhlIHNpbmdsZSBjYXNlcyBkYXRhZnJhbWUuIApgYGB7cn0KZGZfY29ob3J0IDwtCiAgcmVhZF9leGNlbCgiL1VzZXJzL3JtdnBhZW1lL09uZWRyaXZlL1VHZW50L1BJTVMtVFMgU3lzdGVtYXRpYyBSZXZpZXcgLSBHZW5lcmFsL0RhdGEgZXh0cmFjdGllL2RhdGEgZXh0cmFjdGllLnhsc3giLAogICAgICAgICAgICAgc2hlZXQgPSAiQ29ob3J0cyIsCiAgICAgICAgICAgICBza2lwID0gMSwKICAgICAgICAgICAgIGNvbF9uYW1lcyA9IEZBTFNFKVssLWMoMTozKV0KCgpkZl9jb2hvcnQgPC0gZGZfY29ob3J0ICU+JSB0KCkKZGZfY29ob3J0IDwtIGFzLmRhdGEuZnJhbWUoZGZfY29ob3J0LCBzdHJpbmdzQXNGYWN0b3JzID0gRkFMU0UpCm5tcyA8LSBhcy52ZWN0b3IoZGZfY29ob3J0WzEsXSkKbm1zW2lzLm5hKG5tcyldIDwtICd0bXAnCmNvbG5hbWVzKGRmX2NvaG9ydCkgPC0gbWFrZS51bmlxdWUoYXMuY2hhcmFjdGVyKG5tcykpCmRmX2NvaG9ydCA8LSBkZl9jb2hvcnRbLTEsXQpkZl9jb2hvcnQgPC0gZGZfY29ob3J0ICU+JSBzZWxlY3QoLWNvbnRhaW5zKCJ0bXAiKSkKZGZfY29ob3J0IDwtIGRmX2NvaG9ydCAlPiUgc2VsZWN0KC12YXJpYWJsZV9pZCkKCmRmX2NvaG9ydCA8LSBkZl9jb2hvcnQgJT4lIAogIG11dGF0ZV9hbGwoZnVucyhzdHJfcmVwbGFjZSguLCAiWWVzIiwgInllcyIpKSkKZGZfY29ob3J0IDwtIGRmX2NvaG9ydCAlPiUgCiAgbXV0YXRlX2FsbChmdW5zKHN0cl9yZXBsYWNlKC4sICJObyIsICJubyIpKSkKZGZfY29ob3J0IDwtIGRmX2NvaG9ydCAlPiUgCiAgbXV0YXRlX2FsbChmdW5zKHN0cl9yZXBsYWNlKC4sICJwb3MiLCAieWVzIikpKQpkZl9jb2hvcnQgPC0gZGZfY29ob3J0ICU+JSAKICBtdXRhdGVfYWxsKGZ1bnMoc3RyX3JlcGxhY2UoLiwgIm5lZyIsICJubyIpKSkKCmRmX2NvaG9ydCA8LSBkZl9jb2hvcnQgJT4lCiAgcmVwbGFjZV93aXRoX25hX2FsbChjb25kaXRpb24gPSB+LnggPT0gIk5BIikKCmRmX2NvaG9ydCA8LSB0eXBlX2NvbnZlcnQoZGZfY29ob3J0KQoKZGZfY29ob3J0IDwtIGRmX2NvaG9ydFtjb2xTdW1zKCFpcy5uYShkZl9jb2hvcnQpKSA+IDBdCgpkZl9jb2hvcnQgPC0gZGZfY29ob3J0ICU+JSBmaWx0ZXIoZG9pICE9ICJodHRwczovL2RvaS5vcmcvMTAuMTE4Ni9zMTM2MTMtMDIwLTAwNjkwLTgiKSAlPiUgZmlsdGVyKGRvaSAhPSAiaHR0cHM6Ly9kb2kub3JnLzEwLjEwMTYvUzAxNDAtNjczNigyMCkzMTEwMy1YIikKCmRmX2NvaG9ydF9jb250cm9scyA8LSBkZl9jb2hvcnQKCmRmX2NvaG9ydCA8LSBkZl9jb2hvcnQgJT4lIGZpbHRlcihjb2hvcnRfdHlwZSA9PSAiY292aWQiKQoKZGZfY29ob3J0JGRhdGVfb2ZfcHVibGljYXRpb24gPC0gYXMuRGF0ZShkZl9jb2hvcnQkZGF0ZV9vZl9wdWJsaWNhdGlvbiwgb3JpZ2luID0gIjE4OTktMTItMzAiKQoKd3JpdGUuY3N2KGRmX2NvaG9ydCwgcGFzdGUwKCIuL2RhdGEvZGZfY29ob3J0LmNzdiIpKQoKI2RhdGF0YWJsZShkZl9jb2hvcnQsIGNhcHRpb24gPSAiQ29ob3J0IGRhdGFmcmFtZSIpCmBgYAoKPGJ1dHRvbiBvbmNsaWNrPSJsb2NhdGlvbi5ocmVmPSdodHRwczovL2dpdGh1Yi5jb20vcm12cGFlbWUvUElNU19UUy9ibG9iL21hc3Rlci9kYXRhL2RmX2NvaG9ydC5jc3YnIiB0eXBlPSJidXR0b24iPgogICAgICAgICBEb3dubG9hZCBjb2hvcnQgZGF0YSBhcyAuY3N2IG9uIEdpdGh1YjwvYnV0dG9uPgoKIyBEZXNjcmlwdGl2ZSBzdGF0aXN0aWNzIHsudGFic2V0fQojIyBHZW5lcmFsCgoqKkNsaWNrIG9uIHRoZSBhbnkgb2YgdGhlIHRhYnMgYWJvdmUgdG8gc2VlIGRlc2NyaXB0aXZlIHN0YXRpc3RpY3MgZm9yIGV2ZXJ5IHZhcmlhYmxlKiogICAgICAKCiMjIFNpbmdsZSBjYXNlcwoqKkhvdyB0byByZWFkKiogIApVbmRlciAiVmFyaWFibGUgdHlwZTogbG9naWNhbCIsIHRoZSBudW1iZXIgb2YgdHJ1ZS9mYWxzZXMgYXJlIGRlcGljdGVkLiBFLmcuIGF0IHRoZSB0b3Agd2UgY2FuIHNlZSB0aGF0IHRoZXJlIGFyZSA5NSBudW1iZXIgb2Ygcm93cyAoPSA5NSBwYXRpZW50cykuIE92ZXJ3ZWlnaHQgaGFzIDc5IG1pc3NpbmcgdmFsdWVzICgxNyUgaXMgY29tcGxldGUpLCB3aGljaCBtZWFucyB0aGF0IDk1LTc5PTE2IHBhdGllbnRzIGhhdmUgZWl0aGVyICJUUlVFIiBvciAiRkFMU0UiIGZvciBvdmVyd2VpZ2h0LiBPZiB0aGVzZSAxNiwgOSBhcmUgbWFya2VkIGFzICJUUlVFIiBmb3Igb3ZlcndlaWdodC4gCgo8YnV0dG9uIG9uY2xpY2s9ImxvY2F0aW9uLmhyZWY9J2h0dHBzOi8vZ2l0aHViLmNvbS9ybXZwYWVtZS9QSU1TX1RTL2Jsb2IvbWFzdGVyL2RhdGEvc2luZ2xlY2FzZXNfZGVzY3JpcHRpdmVzdGF0cy5jc3YnIiB0eXBlPSJidXR0b24iPgogICAgICAgICBEb3dubG9hZCBkYXRhIGFzIC5jc3Ygb24gR2l0aHViPC9idXR0b24+CiAgICAgICAgIAoKYGBge3J9CiNza2ltKGRmX3NpbmdsZWNhc2VzKQp3cml0ZS5jc3Yoc2tpbShkZl9zaW5nbGVjYXNlcyksIHBhc3RlMCgiLi9kYXRhL3NpbmdsZWNhc2VzX2Rlc2NyaXB0aXZlc3RhdHMuY3N2IikpCmBgYAoKIyMgQ29ob3J0cwoqKkhvdyB0byByZWFkKiogIApUaGUgc3VtIGNvbHVtbiBlcXVhbHMgdGhlIHN1bSBvZiBhbGwgaW5kaXZpZHVhbHMsIGUuZy4gc3VtKHRvdF9jYXNlc19uKSBtZWFucyB0aGF0IHRoZXJlIGFyZSA1OTIgcGF0aWVudHMgaW4gdG90YWwgaW4gdGhlIGNvaG9ydHM7IHN1bShvdXRjb21lX2RlYXRoX24pIG1lYW5zIHRoYXQgOSBwYXRpZW50cyBkaWVkLiAKClRoZSAiUHJjdF90b3RhbCIgY29sdW1uIGlzIHRoZSBwZXJjZW50YWdlIG9mIGUuZy4gZGVhdGggKDkvNTkyKS4gT25seSBtYWtlcyBzZW5zZSB3aGVyZSBuIGlzIHJlcG9ydGVkIGUuZy4gdGhlcmFweSAobm90IGZvciBsYWIgdmFsdWVzKS4KCjxidXR0b24gb25jbGljaz0ibG9jYXRpb24uaHJlZj0naHR0cHM6Ly9naXRodWIuY29tL3JtdnBhZW1lL1BJTVNfVFMvYmxvYi9tYXN0ZXIvZGF0YS9jb2hvcnRfZGVzY3JpcHRpdmVzdGF0cy5jc3YnIiB0eXBlPSJidXR0b24iPgogICAgICAgICBEb3dubG9hZCBkYXRhIGFzIC5jc3Ygb24gR2l0aHViPC9idXR0b24+CgpgYGB7cn0Kc2tpbXN1bSA8LSBza2ltX3dpdGgobnVtZXJpYyA9IHNmbChzdW0gPSB+IHN1bSguLCBuYS5ybSA9IFRSVUUpLCBQcmN0X3RvdGFsID0gfiBzdW0oLiwgbmEucm0gPSBUUlVFKS9zdW0oZGZfY29ob3J0JHRvdF9jYXNlc19uKSoxMDApLCBhcHBlbmQgPSBUUlVFKQojc2tpbXN1bShkZl9jb2hvcnQpCndyaXRlLmNzdihza2ltc3VtKGRmX2NvaG9ydCksIHBhc3RlMCgiLi9kYXRhL2NvaG9ydF9kZXNjcmlwdGl2ZXN0YXRzLmNzdiIpKQpgYGAKCiMjIEhpc3RvcmljYWwgY29udHJvbHMKCjxidXR0b24gb25jbGljaz0ibG9jYXRpb24uaHJlZj0naHR0cHM6Ly9naXRodWIuY29tL3JtdnBhZW1lL1BJTVNfVFMvYmxvYi9tYXN0ZXIvZGF0YS9oaXN0b3JpY2FsY29udHJvbHNfZGVzY3JpcHRpdmVzdGF0cy5jc3YnIiB0eXBlPSJidXR0b24iPgogICAgICAgICBEb3dubG9hZCBkYXRhIGFzIC5jc3Ygb24gR2l0aHViPC9idXR0b24+CiAgICAgICAgIApgYGB7cn0KZGZfY29ob3J0X2NvbnRyb2xzX3N0YXRzIDwtIGRmX2NvaG9ydF9jb250cm9scyAlPiUgZmlsdGVyKGNvaG9ydF90eXBlID09ICJjb250cm9sIikKZGZfY29ob3J0X2NvbnRyb2xzX3N0YXRzIDwtIGRmX2NvaG9ydF9jb250cm9sc19zdGF0c1tjb2xTdW1zKCFpcy5uYShkZl9jb2hvcnRfY29udHJvbHNfc3RhdHMpKSA+IDBdCnNraW1zdW0gPC0gc2tpbV93aXRoKG51bWVyaWMgPSBzZmwoc3VtID0gfiBzdW0oLiwgbmEucm0gPSBUUlVFKSwgUHJjdF90b3RhbCA9IH4gc3VtKC4sIG5hLnJtID0gVFJVRSkvc3VtKGRmX2NvaG9ydF9jb250cm9sc19zdGF0cyR0b3RfY2FzZXNfbikqMTAwKSwgYXBwZW5kID0gVFJVRSkKI3NraW1zdW0oZGZfY29ob3J0X2NvbnRyb2xzX3N0YXRzKQoKd3JpdGUuY3N2KHNraW1zdW0oZGZfY29ob3J0X2NvbnRyb2xzX3N0YXRzKSwgcGFzdGUwKCIuL2RhdGEvaGlzdG9yaWNhbGNvbnRyb2xzX2Rlc2NyaXB0aXZlc3RhdHMuY3N2IikpCgp3cml0ZS5jc3YoZGZfY29ob3J0X2NvbnRyb2xzX3N0YXRzLCBwYXN0ZTAoIi4vZGF0YS9kZl9jb2hvcnRfY29udHJvbHNfc3RhdHMuY3N2IikpCmBgYAoKCiMgRGF0YSBleHBsb3JhdGlvbgoKKipJbXBvcnRhbnQqKiAKCkZvciB0aGUgY29ob3J0cywgcGVyY2VudGFnZXMgZGVzY3JpYmUgdGhlIHRvdGFsIChlLmcuIHBvc2l0aXZlKSBjYXNlcywgZGl2aWRlZCBieSB0aGUgc3VtIG9mIHRoZSB0b3RhbCBjYXNlcyAqKm9mIHN0dWRpZXMgcmVwb3J0aW5nIHRoZSB2YXJpYWJsZSoqLgoKIyMgQ2FzZXMgaW4gZnVuY3Rpb24gb2YgQ09WSUQgcGFuZGVtaWMKClRvIGludmVzdGlnYXRlIHRoZSByZWxhdGlvbnNoaXAgb2YgdGhlIHB1Ymxpc2hlZCBQSU1TIGNhc2VzIHdpdGggdGhlIG9uZ29pbmcgQ09WSUQtMTkgcGFuZGVtaWMsIHRoZSBjYXNlIGRhdGEgZnJvbSBbSm9obnMgSG9wa2luc10oaHR0cHM6Ly9naXRodWIuY29tL0NTU0VHSVNhbmREYXRhL0NPVklELTE5KSB3YXMgZG93bmxvYWRlZCAoYW5kIGFkZGVkIHRvIHRoaXMgcmVwb3NpdG9yeSkuCgpUaGUgbGlzdCB3YXMgZmlsdGVyZWQgb24gdGhlIFVLLCBVUywgSXRhbHkgYW5kIEZyYW5jZSwgYXMgdGhlc2UgY291bnRyeSBjb250cmlidXRlIHRoZSBtb3N0IHRvIG91ciBkYXRhc2V0LiAKCkNhdmVhdDogdGhpcyBpcyBhIGRpc3RvcmVkIGltYWdlIG9mIHRoZSBQSU1TIGNhc2VzOiBhcyB0aGUgY2FzZXMgYXJlIHB1Ymxpc2hlZCB0b2dldGhlciwgdGhlaXIgdHJ1ZSBkYXRlIG9mIGRpYWdub3NpcyBpcyB1bmtub3duLiAKCmBgYHtyfQoKZmlyc3RkaWZmIDwtIGZ1bmN0aW9uKHgpIHsKICAgc2hpZnRlZCA8LSBjKDAseFsxOihsZW5ndGgoeCktMSldKQogICB4LXNoaWZ0ZWQKICAgfQoKVVNBX2Nhc2VzIDwtIHJlYWRfY3N2KCIuL2RhdGEvdGltZV9zZXJpZXNfY292aWQxOV9jb25maXJtZWRfVVMuY3N2IikKVVNBX2Nhc2VzIDwtIFVTQV9jYXNlcyAlPiUgc2VsZWN0KC1jKFVJRCwgaXNvMiwgaXNvMywgY29kZTMsIEZJUFMsIEFkbWluMiwgUHJvdmluY2VfU3RhdGUsIExhdCwgTG9uZ18sIENvbWJpbmVkX0tleSkpCgpuYW1lcyhVU0FfY2FzZXMpW25hbWVzKFVTQV9jYXNlcykgPT0gJ0NvdW50cnlfUmVnaW9uJ10gPC0gIkNvdW50cnkvUmVnaW9uIgoKZ2xvYmFsX2Nhc2VzIDwtIHJlYWRfY3N2KCIuL2RhdGEvdGltZV9zZXJpZXNfY292aWQxOV9jb25maXJtZWRfZ2xvYmFsLmNzdiIpCmdsb2JhbF9jYXNlcyA8LSBnbG9iYWxfY2FzZXMgJT4lIHNlbGVjdCgtYyhgUHJvdmluY2UvU3RhdGVgLCBMYXQsIExvbmcpKQoKZ2xvYmFsX2Nhc2VzIDwtIHJiaW5kKFVTQV9jYXNlcywgZ2xvYmFsX2Nhc2VzKQoKZ2xvYmFsX2Nhc2VzIDwtIGdsb2JhbF9jYXNlcyAlPiUgbWVsdCgpCmdsb2JhbF9jYXNlcyR2YXJpYWJsZSA8LSBhcy5EYXRlKGdsb2JhbF9jYXNlcyR2YXJpYWJsZSwgZm9ybWF0ID0gIiVtLyVkLyV5IikKY29sbmFtZXMoZ2xvYmFsX2Nhc2VzKSA8LSBjKCJjb3VudHJ5IiwgImRhdGVfb2ZfcHVibGljYXRpb24iLCAidG90X2Nhc2VzX2NvdmlkIikKZ2xvYmFsX2Nhc2VzIDwtIGdsb2JhbF9jYXNlcyAlPiUgZmlsdGVyKGNvdW50cnkgPT0gIlVuaXRlZCBLaW5nZG9tIiAgfCBjb3VudHJ5ID09ICJJdGFseSIgfCBjb3VudHJ5ID09ICJGcmFuY2UiIHwgY291bnRyeSA9PSAiVVMiKQphbGxfZ2xvYl9jYXNlcyA8LSBnbG9iYWxfY2FzZXMgJT4lIGdyb3VwX2J5KGRhdGVfb2ZfcHVibGljYXRpb24pICU+JSBzdW1tYXJpc2UodG90YWxfY2FzZXMgPSBzdW0odG90X2Nhc2VzX2NvdmlkKSkKYWxsX2dsb2JfY2FzZXMkbmV3Y2FzZXMgPC0gZmlyc3RkaWZmKGFsbF9nbG9iX2Nhc2VzJHRvdGFsX2Nhc2VzKQphbGxfZ2xvYl9jYXNlcyRuZXdjYXNlX3JvbGw3IDwtIHpvbzo6cm9sbG1lYW4oYWxsX2dsb2JfY2FzZXMkbmV3Y2FzZXMsIGsgPSA3LCBmaWxsID0gTkEpCgpldm9fY2FzZXMgPC0gcmJpbmQoZGZfY29ob3J0ICU+JSBzZWxlY3QodG90X2Nhc2VzX24sIGRhdGVfb2ZfcHVibGljYXRpb24pICU+JSBtdXRhdGUodHlwZSA9ICJjb2hvcnQiKSwgCmRmX3NpbmdsZWNhc2VzICU+JSBzZWxlY3QoZGF0ZV9vZl9wdWJsaWNhdGlvbikgJT4lIG11dGF0ZSh0b3RfY2FzZXNfbiA9IDEsIHR5cGUgPSAic2luZ2xlIikpCgpldm9fY2FzZXMgPC0gcGFkKGV2b19jYXNlcykKZXZvX2Nhc2VzJHRvdF9jYXNlc19uW2lzLm5hKGV2b19jYXNlcyR0b3RfY2FzZXNfbildIDwtIDAKZXZvX2Nhc2VzJGN1bXBsb3QgPC0gY3Vtc3VtKGV2b19jYXNlcyR0b3RfY2FzZXNfbikKCmZ1bGxfZGF0YSA8LSBtZXJnZShldm9fY2FzZXMsIGFsbF9nbG9iX2Nhc2VzLCBhbGwgPSBUUlVFKQoKcDEgPC0gZ2dwbG90KGZ1bGxfZGF0YSAsIGFlcyh4ID0gZGF0ZV9vZl9wdWJsaWNhdGlvbiwgeSA9IGN1bXBsb3QpKSArCiAgICAgICAgZ2VvbV9jb2wocG9zaXRpb24gPSAiZG9kZ2UiLCBjb2wgPSB3ZXNfcGFsZXR0ZSgiUm95YWwxIilbMl0sIGZpbGwgPSB3ZXNfcGFsZXR0ZSgiUm95YWwxIilbMl0pICsgCiAgICAgICAgdGhlbWVfYncoKSArIGdlb21fbGluZShhZXMoeCA9IGRhdGVfb2ZfcHVibGljYXRpb24sIHkgPSBuZXdjYXNlX3JvbGw3LzE3NSkpICsKICAgICAgICBsYWJzKHggPSAiRGF0ZSIsIHkgPSAiY3VtdWxhdGl2ZSBudW1iZXIgb2YgY2FzZXMiLCB0aXRsZSA9ICJOdW1iZXIgb2YgcHVibGlzaGVkIGNhc2VzIikgKyAgc2NhbGVfeF9kYXRlKGxpbWl0cyA9IGFzLkRhdGUoYygnMjAyMC0wMS0xNScsJzIwMjAtMDctMDEnKSkpICsgc2NhbGVfeV9jb250aW51b3VzKAogICAgImN1bXVsYXRpdmUgbnVtYmVyIG9mIHB1Ymxpc2hlZCBjYXNlcyIsIAogICAgc2VjLmF4aXMgPSBzZWNfYXhpcyh+IC4gKiAxNzUsIG5hbWUgPSAibmV3IENPVklELTE5IGNhc2VzICg3LWRheSBhdmVyYWdlKSIpCiAgKQoKcDEgCgpnZ3NhdmUocDEsIGZpbGVuYW1lID0gIi4vcGxvdHMvY292aWRfZXZvX3RvdGFsLnBuZyIsIGRwaSA9IDMwMCwgaGVpZ2h0PTcsIHdpZHRoPTEwKQpnZ3NhdmUocDEsIGZpbGVuYW1lID0gIi4vcGxvdHMvY292aWRfZXZvX3RvdGFsLnN2ZyIsIGRwaSA9IDMwMCwgaGVpZ2h0PTcsIHdpZHRoPTEwKQpnZ3NhdmUocDEsIGZpbGVuYW1lID0gIi4vcGxvdHMvY292aWRfZXZvX3RvdGFsLnBkZiIsIGRwaSA9IDMwMCwgaGVpZ2h0PTcsIHdpZHRoPTEwKQoKCgphbGxfZ2xvYl9jYXNlcyA8LSBnbG9iYWxfY2FzZXMgJT4lIGdyb3VwX2J5KGRhdGVfb2ZfcHVibGljYXRpb24sIGNvdW50cnkpICU+JSBzdW1tYXJpc2UodG90YWxfY2FzZXMgPSBzdW0odG90X2Nhc2VzX2NvdmlkKSkgJT4lIHVuZ3JvdXAoKQoKCmFsbF9nbG9iX2Nhc2VzIDwtIGFsbF9nbG9iX2Nhc2VzICU+JSBncm91cF9ieShjb3VudHJ5KSAlPiUKICBtdXRhdGUobmV3Y2FzZXMgPSBmaXJzdGRpZmYodG90YWxfY2FzZXMpKSAlPiUgdW5ncm91cCgpCgojYWxsX2dsb2JfY2FzZXMkbmV3Y2FzZXMgPC0gZmlyc3RkaWZmKGFsbF9nbG9iX2Nhc2VzJHRvdGFsX2Nhc2VzKQphbGxfZ2xvYl9jYXNlcyA8LSBhbGxfZ2xvYl9jYXNlcyAlPiUgZ3JvdXBfYnkoY291bnRyeSkgICU+JSBtdXRhdGUobmV3Y2FzZV9yb2xsNyA9IHpvbzo6cm9sbG1lYW4obmV3Y2FzZXMsIGsgPSA3LCBmaWxsID0gTkEpKSAKCmV2b19jYXNlcyA8LSByYmluZChkZl9jb2hvcnQgJT4lIHNlbGVjdCh0b3RfY2FzZXNfbiwgZGF0ZV9vZl9wdWJsaWNhdGlvbiwgY291bnRyeSkgJT4lIG11dGF0ZSh0eXBlID0gImNvaG9ydCIpLCAKZGZfc2luZ2xlY2FzZXMgJT4lIHNlbGVjdChkYXRlX29mX3B1YmxpY2F0aW9uLCBjb3VudHJ5KSAlPiUgbXV0YXRlKHRvdF9jYXNlc19uID0gMSwgdHlwZSA9ICJzaW5nbGUiKSkKCmNvdW50cnlfYmFycGxvdCA8LSBldm9fY2FzZXMKCmV2b19jYXNlcyA8LSBwYWQoZXZvX2Nhc2VzKQojZXZvX2Nhc2VzJHRvdF9jYXNlc19uW2lzLm5hKGV2b19jYXNlcyR0b3RfY2FzZXNfbildIDwtIDAKI2V2b19jYXNlcyR0b3RfY2FzZXNfbltpcy5uYShldm9fY2FzZXMkdG90X2Nhc2VzX24pXSA8LSAwCmV2b19jYXNlcyA8LSBldm9fY2FzZXMgJT4lIGdyb3VwX2J5KGNvdW50cnkpICU+JSBtdXRhdGUoY3VtcGxvdCA9IGN1bXN1bSh0b3RfY2FzZXNfbikpICU+JSB1bmdyb3VwKCkKZXZvX2Nhc2VzIDwtIGV2b19jYXNlcyAlPiUgZmlsbChjb3VudHJ5KQoKCmZ1bGxfZGF0YSA8LSBtZXJnZShldm9fY2FzZXMsIGFsbF9nbG9iX2Nhc2VzLCBhbGwgPSBUUlVFKQpmdWxsX2RhdGFfZmlsdCA8LSBmdWxsX2RhdGEgJT4lIGZpbHRlcihjb3VudHJ5ID09ICJVbml0ZWQgS2luZ2RvbSIgIHwgY291bnRyeSA9PSAiSXRhbHkiIHwgY291bnRyeSA9PSAiRnJhbmNlIiB8IGNvdW50cnkgPT0gIlVTIikKCmZ1bGxfZGF0YV9maWx0IDwtIGZ1bGxfZGF0YV9maWx0ICU+JSBtdXRhdGUoY29udGluZW50ID0gaWZlbHNlKGNvdW50cnkgPT0gIlVTIiwgIlVTIiwgIkV1cm9wZSIpKQoKcDEgPC0gZ2dwbG90KGZ1bGxfZGF0YV9maWx0ICwgYWVzKHggPSBkYXRlX29mX3B1YmxpY2F0aW9uLCB5ID0gY3VtcGxvdCkpICsKICAgICAgICBnZW9tX2NvbChwb3NpdGlvbiA9ICJkb2RnZSIsIGFlcyhmaWxsID0gY291bnRyeSwgY29sID0gY291bnRyeSkpICsgCiAgICAgICAgdGhlbWVfYncoKSArIAogICAgICAgIHNjYWxlX2NvbG9yX21hbnVhbCh2YWx1ZXMgPSB3ZXNfcGFsZXR0ZSgiRGFyamVlbGluZzIiKVtjKDEsMyw0LDIpXSkgKwogIHNjYWxlX2ZpbGxfbWFudWFsKHZhbHVlcyA9IHdlc19wYWxldHRlKCJEYXJqZWVsaW5nMiIpW2MoMSwzLDQsMildKSArCiAgICAgICAgZ2VvbV9saW5lKGFlcyh4ID0gZGF0ZV9vZl9wdWJsaWNhdGlvbiwgeSA9IG5ld2Nhc2Vfcm9sbDcvMTAwLCBjb2wgPSBjb3VudHJ5KSkgKwogICAgICAgIGxhYnMoeCA9ICJEYXRlIiwgeSA9ICJjdW11bGF0aXZlIG51bWJlciBvZiBjYXNlcyAoYmFycykiLCB0aXRsZSA9ICJOdW1iZXIgb2YgcHVibGlzaGVkIGNhc2VzLCBwZXIgY291bnRyeSIpICsKICAgICAgICBzY2FsZV94X2RhdGUobGltaXRzID0gYXMuRGF0ZShjKCcyMDIwLTAzLTAxJywnMjAyMC0wNy0wMScpKSkgKyBzY2FsZV95X2NvbnRpbnVvdXMoICAgICJjdW11bGF0aXZlIG51bWJlciBvZiBwdWJsaXNoZWQgY2FzZXMgKGJhcnMpIiwgCiAgICBzZWMuYXhpcyA9IHNlY19heGlzKH4gLiAqIDEwMCwgbmFtZSA9ICJuZXcgQ09WSUQtMTkgY2FzZXMgKDctZGF5IGF2ZXJhZ2UsIGxpbmVzKSIpIAogICkgKyAKICAgICAgdGhlbWUobGVnZW5kLnBvc2l0aW9uPSJib3R0b20iKSArIAogICAgICBmYWNldF93cmFwKH5jb250aW5lbnQsIHNjYWxlcyA9ICJmcmVlX3kiKQoKcDEKCmdnc2F2ZShwMSwgZmlsZW5hbWUgPSAiLi9wbG90cy9jb3ZpZF9ldm9fcGVyY291bnRyeS5wbmciLCBkcGkgPSAzMDAsIGhlaWdodD03LCB3aWR0aD0xMCkKZ2dzYXZlKHAxLCBmaWxlbmFtZSA9ICIuL3Bsb3RzL2NvdmlkX2V2b19wZXJjb3VudHJ5LnN2ZyIsIGRwaSA9IDMwMCwgaGVpZ2h0PTcsIHdpZHRoPTEwKQpnZ3NhdmUocDEsIGZpbGVuYW1lID0gIi4vcGxvdHMvY292aWRfZXZvX3BlcmNvdW50cnkucGRmIiwgZHBpID0gMzAwLCBoZWlnaHQ9Nywgd2lkdGg9MTApCgpgYGAKCiMjIFBJTVMgY2FzZXMgYnkgY291bnRyeSAKCmBgYHtyfQoKZ2dwbG90KGNvdW50cnlfYmFycGxvdCwgYWVzKHggPSByZW9yZGVyKGNvdW50cnksIC10b3RfY2FzZXNfbiksIHkgPSB0b3RfY2FzZXNfbiwgZmlsbCA9IHR5cGUpKSArIAogICAgICAgIGdlb21fYmFyKHN0YXQgPSAnaWRlbnRpdHknKSArCiAgICAgICAgdGhlbWVfYncoKSArCiAgICAgICAgc2NhbGVfZmlsbF9tYW51YWwodmFsdWVzID0gd2VzX3BhbGV0dGUoIlJveWFsMSIpKSArIAogICAgICAgIGxhYnMoeCA9ICJDb3VudHJ5IiwgeSA9ICJUb3RhbCBjYXNlcyIsIHRpdGxlID0gIkNhc2VzIHBlciBjb3VudHJpZXMgaW4gZGF0YXNldCIpCgpgYGAKCgojIyBUb3RhbCBjYXNlcyBhbmQgZGVhdGhzCmBgYHtyfQojdmFyX2lkX2NvaG9ydCA9ICJvdXRjb21lX2RlYXRoX24iCiN2YXJfaWRfc2luZ2xlID0gIm91dGNvbWVfZGVhdGgiCiN2YXJfaWQgPSAiZGVhdGhzIgptYWtlQmFycGxvdCgib3V0Y29tZV9kZWF0aF9uIiwgIm91dGNvbWVfZGVhdGgiLCAiZGVhdGhzIikKYGBgCgojIyBTZXgKYGBge3J9Cm5fY29ob3J0IDwtIGRmX2NvaG9ydCAlPiUgc2VsZWN0KHRvdF9jYXNlc19uKSAlPiUgc3VtKCkKdmFyX2NvaG9ydCA8LSBkZl9jb2hvcnQgJT4lIHNlbGVjdChjb250YWlucygic2V4IikpCnZhcl9jb2hvcnQgPC0gY29sU3Vtcyh2YXJfY29ob3J0LCBuYS5ybSA9IFRSVUUpCnZhcl9jb2hvcnQgPC0gdmFyX2NvaG9ydC9zdW0oZGZfY29ob3J0JHRvdF9jYXNlc19uKSoxMDAKdmFyX2NvaG9ydFsic2V4X25hIl0gPC0gKDEwMCAtIHZhcl9jb2hvcnRbInNleF9tIl0gLSB2YXJfY29ob3J0WyJzZXhfZiJdKQoKdmFyX2NvbnRyb2wgPC0gZGZfY29ob3J0X2NvbnRyb2xzICU+JSBmaWx0ZXIoY29ob3J0X2lkID09ICJQb3VsZXR0eSAtIGNvbnRyb2wiKSAlPiUgc2VsZWN0KGNvbnRhaW5zKCJzZXgiKSkKdmFyX2NvbnRyb2wgPC0gY29sU3Vtcyh2YXJfY29udHJvbCwgbmEucm0gPSBUUlVFKQp2YXJfY29udHJvbCA8LSB2YXJfY29udHJvbC9zdW0oZGZfY29ob3J0X2NvbnRyb2xzICU+JSBmaWx0ZXIoY29ob3J0X2lkID09ICJQb3VsZXR0eSAtIGNvbnRyb2wiKSAlPiUgc2VsZWN0KHRvdF9jYXNlc19uKSkqMTAwCnZhcl9jb250cm9sWyJzZXhfbmEiXSA8LSAoMTAwIC0gdmFyX2NvbnRyb2xbInNleF9tIl0gLSB2YXJfY29udHJvbFsic2V4X2YiXSkKCm5fc2luZ2xlIDwtIGRmX3NpbmdsZWNhc2VzICU+JSBucm93KCkKdmFyX3NpbmdsZSA8LSBkZl9zaW5nbGVjYXNlcyAlPiUgc2VsZWN0KGNvbnRhaW5zKCJzZXgiKSkKdmFyX3NpbmdsZSRzZXhfbSA8LSBpZmVsc2UodmFyX3NpbmdsZSRzZXggPT0gIk0iLCBUUlVFLCBGQUxTRSkKdmFyX3NpbmdsZSRzZXhfZiA8LSBpZmVsc2UodmFyX3NpbmdsZSRzZXggPT0gIkYiLCBUUlVFLCBGQUxTRSkKY29scyA8LSBzYXBwbHkodmFyX3NpbmdsZSwgaXMubG9naWNhbCkKdmFyX3NpbmdsZVssY29sc10gPC0gbGFwcGx5KHZhcl9zaW5nbGVbLGNvbHNdLCBhcy5udW1lcmljKQp2YXJfc2luZ2xlIDwtIGNvbFN1bXModmFyX3NpbmdsZSAlPiUgc2VsZWN0KC1zZXgpLCBuYS5ybSA9IFRSVUUpCnZhcl9zaW5nbGUgPC0gdmFyX3NpbmdsZS9ucm93KGRmX3NpbmdsZWNhc2VzKSoxMDAKdmFyX3NpbmdsZVsic2V4X25hIl0gPC0gKDEwMCAtIHZhcl9zaW5nbGVbInNleF9tIl0gLSB2YXJfc2luZ2xlWyJzZXhfZiJdKQoKYmFyX2RmX3ByY3QgPC0gZGF0YS5mcmFtZSgKICB4ID0gYygibWFsZXMiLCAiZmVtYWxlcyIsICJtaXNzaW5nIiwgIm1hbGVzIiwgImZlbWFsZXMiLCAibWlzc2luZyIsICJtYWxlcyIsICJmZW1hbGVzIiwgIm1pc3NpbmciKSwKICB2YWxzID0gYyh2YXJfc2luZ2xlLCB2YXJfY29ob3J0LCB2YXJfY29udHJvbCksCiAgY29sID0gYyhyZXAoInNpbmdsZSIsIGxlbmd0aCh2YXJfc2luZ2xlKSksIHJlcCgiY29ob3J0cyIsIGxlbmd0aCh2YXJfY29ob3J0KSksIHJlcCgiaGlzdG9yIGN0cmwiLCBsZW5ndGgodmFyX2NvbnRyb2wpKQopKQoKcF9wcmN0IDwtIGdncGxvdChiYXJfZGZfcHJjdCwgYWVzKHggPSBjb2wsIHkgPSAgdmFscywgZmlsbCA9IHgpKSArCiAgICBnZW9tX2JhcihzdGF0ID0gImlkZW50aXR5IiwgcG9zaXRpb24gPSAic3RhY2siKSArCiAgICB0aGVtZV9idygpICsgCiAgICBsYWJzKHRpdGxlID0gIk1hbGUvZmVtYWxlIGRpc3RyaWJ1dGlvbiBpbiBkYXRhc2V0Iiwgc3VidGl0bGUgPSAiUHJjdCIsIHggPSAic2V4IiwgeSA9ICIlIiwgY29sID0gIiAiKSAgKyBsaW1zKHkgPSBjKDAsMTAwKSkgKyB0aGVtZShheGlzLnRleHQueD1lbGVtZW50X3RleHQoYW5nbGU9OTAsIGhqdXN0PTEpKSsKICBzY2FsZV9maWxsX21hbnVhbCh2YWx1ZXMgPSB3ZXNfcGFsZXR0ZSgiUm95YWwxIikpCnBfcHJjdApgYGAKCgpgYGB7cn0KdmFyX2NvaG9ydCA8LSBkZl9jb2hvcnQgJT4lIHNlbGVjdChjb250YWlucygic2V4IikgfCAoImNvaG9ydF9pZCIpIHwgInRvdF9jYXNlc19uIikKc2V4X2YgPC0gdmFyX2NvaG9ydCAlPiUgZ3JvdXBfYnkoY29ob3J0X2lkKSAlPiUgc3VtbWFyaXplKHByY3QgPSBzZXhfZi90b3RfY2FzZXNfbikgJT4lICBtdXRhdGUoc2V4ID0gImZlbWFsZSIpCnNleF9tIDwtIHZhcl9jb2hvcnQgJT4lIGdyb3VwX2J5KGNvaG9ydF9pZCkgJT4lIHN1bW1hcml6ZShwcmN0ID0gc2V4X20vdG90X2Nhc2VzX24pICU+JSBtdXRhdGUoc2V4ID0gIm1hbGUiKQpzZXhfYWxsIDwtIHJiaW5kKHNleF9mLCBzZXhfbSkKCnBfc2V4X2NvaG9ydCA8LSBnZ3Bsb3Qoc2V4X2FsbCwgYWVzKHkgPSBjb2hvcnRfaWQsIHggPSBwcmN0LCBmaWxsID0gc2V4KSkgKyAKICAgICAgICAgIGdlb21fYmFyKHN0YXQgPSAiaWRlbnRpdHkiLCBwb3NpdGlvbiA9ICJmaWxsIikgKyAKICAgICAgICAgIHRoZW1lX2J3KCkgKyBsYWJzKHggPSAiIikgKyAKICAgICAgICAgIHNjYWxlX2ZpbGxfbWFudWFsKHZhbHVlcyA9IHdlc19wYWxldHRlKCJSb3lhbDEiKSkKCnZhcl9jb250cm9scyA8LSBkZl9jb2hvcnRfY29udHJvbHMgJT4lIGZpbHRlcihjb2hvcnRfaWQgPT0gIlBvdWxldHR5IC0gY29udHJvbCIpICU+JSBzZWxlY3QoY29udGFpbnMoInNleCIpIHwgKCJjb2hvcnRfaWQiKSB8ICJ0b3RfY2FzZXNfbiIpCnNleF9mIDwtIHZhcl9jb250cm9scyAlPiUgZ3JvdXBfYnkoY29ob3J0X2lkKSAlPiUgc3VtbWFyaXplKHByY3QgPSBzZXhfZi90b3RfY2FzZXNfbikgJT4lIG11dGF0ZShzZXggPSAiZmVtYWxlIikKc2V4X20gPC0gdmFyX2NvbnRyb2xzICU+JSBncm91cF9ieShjb2hvcnRfaWQpICU+JSBzdW1tYXJpemUocHJjdCA9IHNleF9tL3RvdF9jYXNlc19uKSAlPiUgbXV0YXRlKHNleCA9ICJtYWxlIikKc2V4X2FsbCA8LSByYmluZChzZXhfZiwgc2V4X20pCgpwX3NleF9jb250cm9scyA8LSBnZ3Bsb3Qoc2V4X2FsbCwgYWVzKHkgPSBjb2hvcnRfaWQsIHggPSBwcmN0LCBmaWxsID0gc2V4KSkgKyAKICAgICAgICAgIGdlb21fYmFyKHN0YXQgPSAiaWRlbnRpdHkiLCBwb3NpdGlvbiA9ICJmaWxsIikgKyAKICAgICAgICAgIHRoZW1lX2J3KCkgKyBsYWJzKHggPSAiIikgKyAKICAgICAgICAgIHNjYWxlX2ZpbGxfbWFudWFsKHZhbHVlcyA9IHdlc19wYWxldHRlKCJSb3lhbDEiKSkKCm5fc2luZ2xlIDwtIGRmX3NpbmdsZWNhc2VzICU+JSBucm93KCkKdmFyX3NpbmdsZSA8LSBkZl9zaW5nbGVjYXNlcyAlPiUgc2VsZWN0KGNvbnRhaW5zKCJzZXgiKSkKdmFyX3NpbmdsZSRzZXhfbSA8LSBpZmVsc2UodmFyX3NpbmdsZSRzZXggPT0gIk0iLCBUUlVFLCBGQUxTRSkKdmFyX3NpbmdsZSRzZXhfZiA8LSBpZmVsc2UodmFyX3NpbmdsZSRzZXggPT0gIkYiLCBUUlVFLCBGQUxTRSkKY29scyA8LSBzYXBwbHkodmFyX3NpbmdsZSwgaXMubG9naWNhbCkKdmFyX3NpbmdsZVssY29sc10gPC0gbGFwcGx5KHZhcl9zaW5nbGVbLGNvbHNdLCBhcy5udW1lcmljKQp2YXJfc2luZ2xlIDwtIGNvbFN1bXModmFyX3NpbmdsZSAlPiUgc2VsZWN0KC1zZXgpLCBuYS5ybSA9IFRSVUUpCnZhcl9zaW5nbGUgPC0gdmFyX3NpbmdsZS9ucm93KGRmX3NpbmdsZWNhc2VzKSoxMDAKCnNleF9zaW5nbGUgPC0gZGF0YS5mcmFtZShjb2hvcnRfaWQgPSAic2luZ2xlX2Nhc2VzIiwgcHJjdCA9IGModmFyX3NpbmdsZVsic2V4X20iXSwgdmFyX3NpbmdsZVsic2V4X2YiXSksIHNleCA9IGMoIm1hbGUiLCAiZmVtYWxlIikpCgpwX3NleF9zaW5nbGUgPC0gZ2dwbG90KHNleF9zaW5nbGUsIGFlcyh5ID0gY29ob3J0X2lkLCB4ID0gcHJjdCwgZmlsbCA9IHNleCkpICsgCiAgICAgICAgICBnZW9tX2JhcihzdGF0ID0gImlkZW50aXR5IiwgcG9zaXRpb24gPSAiZmlsbCIpICsgCiAgICAgICAgICB0aGVtZV9idygpICsgCiAgICAgICAgICBzY2FsZV9maWxsX21hbnVhbCh2YWx1ZXMgPSB3ZXNfcGFsZXR0ZSgiUm95YWwxIikpCgphIDwtIHBsb3RfZ3JpZChwX3NleF9jb2hvcnQsIHBfc2V4X2NvbnRyb2xzLCBwX3NleF9zaW5nbGUsIGFsaWduID0gInYiLCBucm93ID0gMywgcmVsX2hlaWdodHMgPSBjKDUvNywgMS83LCAxLzcpKQphCmBgYAoKIyMgQWdlIGRpc3RyaWJ1dGlvbgoKYGBge3J9CmNvaG9ydF9hZ2UgPC0gZGZfY29ob3J0X2NvbnRyb2xzICU+JSBzZWxlY3QoY29udGFpbnMoImNvaG9ydF9pZCIpIHwgY29udGFpbnMoImFnZSIpIHwgY29udGFpbnMoImNvaG9ydF90eXBlIikgIHwgY29udGFpbnMoInRvdF9jYXNlc19uIikpCmNvaG9ydF9hZ2UkY29ob3J0X2lkIDwtIHBhc3RlMChjb2hvcnRfYWdlJGNvaG9ydF9pZCwgIiAobiA9ICIsIGNvaG9ydF9hZ2UkdG90X2Nhc2VzX24sIikiKQpjb2hvcnRfYWdlJGFnZV9tZWRfeXJzIDwtIGFzLm51bWVyaWMoY29ob3J0X2FnZSRhZ2VfbWVkX3lycyApCmNvaG9ydF9hZ2UkYWdlX1ExX3lycyA8LSBhcy5udW1lcmljKGNvaG9ydF9hZ2UkYWdlX1ExX3lycykKY29ob3J0X2FnZSRhZ2VfUTNfeXJzIDwtIGFzLm51bWVyaWMoY29ob3J0X2FnZSRhZ2VfUTNfeXJzKQpjb2hvcnRfYWdlJGFnZV9taW5feXJzIDwtIGFzLm51bWVyaWMoY29ob3J0X2FnZSRhZ2VfbWluX3lycykKY29ob3J0X2FnZSRhZ2VfbWF4X3lycyA8LSBhcy5udW1lcmljKGNvaG9ydF9hZ2UkYWdlX21heF95cnMpCgpjb2hvcnRfYWdlJGRhdGFfZGVzY3IgPC0gaWZlbHNlKCFpcy5uYShjb2hvcnRfYWdlJGFnZV9RMV95cnMpICYgaXMubmEoY29ob3J0X2FnZSRhZ2VfbWluX3lycykgLCAiSVFSIiwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWZlbHNlKGlzLm5hKGNvaG9ydF9hZ2UkYWdlX1ExX3lycykgJiAhaXMubmEoY29ob3J0X2FnZSRhZ2VfbWluX3lycyksICJyYW5nZSIsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZmVsc2UoIWlzLm5hKGNvaG9ydF9hZ2UkYWdlX1ExX3lycykgJiAhaXMubmEoY29ob3J0X2FnZSRhZ2VfbWluX3lycyksICJib3RoIiwgIm5vbmUiKSkpCgpwX2FnZV9jb2hvcnQgPC0gZ2dwbG90KGNvaG9ydF9hZ2UgJT4lIGZpbHRlcihjb2hvcnRfdHlwZSA9PSAiY292aWQiKSwgYWVzKHkgPSBjb2hvcnRfaWQsIHggPSBhZ2VfbWVkX3lycywgY29sID0gZGF0YV9kZXNjcikpICsgCiAgICAgICAgZ2VvbV9wb2ludChzaXplID0gNCkgKyAKICAgICAgICBnZW9tX2Vycm9yYmFyKGFlcyh4bWluPWFnZV9RMV95cnMsIHhtYXg9YWdlX1EzX3lycyksIHdpZHRoPS44LCBwb3NpdGlvbj1wb3NpdGlvbl9kb2RnZSguOSkpICsKICAgICAgICBnZW9tX2Vycm9yYmFyKGFlcyh4bWluPWFnZV9taW5feXJzLCAgeG1heD1hZ2VfbWF4X3lycyksIHdpZHRoPS4yLCBwb3NpdGlvbj1wb3NpdGlvbl9kb2RnZSguOSkpICsKICAgICAgICB0aGVtZV9idygpICsgbGltcyh4ID0gYygwLDIxKSkgKyAKICAgICAgICBsYWJzKHkgPSAiY29ob3J0IiwgeCA9ICIiLCBjb2wgPSAiYmFycyIpICsgdGhlbWUobGVnZW5kLnBvc2l0aW9uPSJ0b3AiKSsKICAgICAgICBzY2FsZV9jb2xvcl9tYW51YWwodmFsdWVzID0gYyh3ZXNfcGFsZXR0ZSgiQm90dGxlUm9ja2V0MiIpWzE6M10sIHdlc19wYWxldHRlKCJCb3R0bGVSb2NrZXQxIilbMl0pKQoKcF9hZ2VfY29udHJvbHMgPC0gZ2dwbG90KGNvaG9ydF9hZ2UgJT4lIGZpbHRlcihjb2hvcnRfdHlwZSAhPSAiY292aWQiKSwgYWVzKHkgPSBjb2hvcnRfaWQsIHggPSBhZ2VfbWVkX3lycywgY29sID0gZGF0YV9kZXNjcikpICsgCiAgICAgICAgZ2VvbV9wb2ludChzaXplID0gNCkgKyAKICAgICAgICBnZW9tX2Vycm9yYmFyKGFlcyh4bWluPWFnZV9RMV95cnMsIHhtYXg9YWdlX1EzX3lycyksIHdpZHRoPS4yLCBwb3NpdGlvbj1wb3NpdGlvbl9kb2RnZSguOSkpICsKICAgICAgICBnZW9tX2Vycm9yYmFyKGFlcyh4bWluPWFnZV9taW5feXJzLCAgeG1heD1hZ2VfbWF4X3lycyksIHdpZHRoPS4yLCBwb3NpdGlvbj1wb3NpdGlvbl9kb2RnZSguOSkpICsKICAgICAgICB0aGVtZV9idygpICsgbGltcyh4ID0gYygwLDIxKSkgKwogICAgICAgIGxhYnMoeSA9ICJjb2hvcnQiLCB4ID0gIiIsIGNvbCA9ICJiYXJzIikgKyB0aGVtZShsZWdlbmQucG9zaXRpb249Im5vbmUiKSsKICAgICAgICBzY2FsZV9jb2xvcl9tYW51YWwodmFsdWVzID0gd2VzX3BhbGV0dGUoIkJvdHRsZVJvY2tldDIiKVsyXSkKCnBfYWdlX3NpbmdsZSA8LSBnZ3Bsb3QoZGZfc2luZ2xlY2FzZXMsIGFlcyh4ID0gYXMubnVtZXJpYyhhZ2UpLCB5ID0gcGFzdGUwKCJzaW5nbGUgY2FzZXMgKG4gPSAiLCBuX3NpbmdsZSwiKSIpKSkgKwogICAgICBnZW9tX3Zpb2xpbihmaWxsID0gd2VzX3BhbGV0dGUoIkRhcmplZWxpbmcyIilbNF0pICsgCiAgICAgIGdlb21fYm94cGxvdCh3aWR0aD0uMywgZmlsbCA9IHdlc19wYWxldHRlKCJEYXJqZWVsaW5nMiIpWzFdKSArIAogICAgICB0aGVtZV9idygpICsgZ2VvbV9iZWVzd2FybShncm91cE9uWD1GQUxTRSwgYWxwaGEgPSAwLjUpICsgbGltcyh4ID0gYygwLDIxKSkgKyAKICAgICAgbGFicyh5ID0gImNvaG9ydCIsIHggPSAiQWdlICh5ZWFycykiKQoKYSA8LSBwbG90X2dyaWQocF9hZ2VfY29ob3J0LCBwX2FnZV9jb250cm9scywgcF9hZ2Vfc2luZ2xlLCBhbGlnbiA9ICJ2IiwgbnJvdyA9IDMsIHJlbF9oZWlnaHRzID0gYygyLzMsIDEvNSwgMS8zKSkKYQpgYGAKCgojIyBTeW1wdG9tcyAKIyMjIFNpbmdsZSBjYXNlcyB7LnRhYnNldH0KIyMjIyBBbGwgc3ltcHRvbXMKV2hlcmUgYXBwbGljYWJsZSwgb3ZlcmxhcCBvZiB2YXJpYWJsZSBpbiB0aGUgc2luZ2xlIGNhc2UgZ3JvdXAgd2FzIHN1bW1hcml6ZWQgd2l0aCBbVXBzZXQgcGxvdHMgKExleCAmIEdlaGxlbmJvcmcsIE5hdHVyZSBNZXRob2RzLCAyMDE0KV0oaHR0cHM6Ly93d3cubmF0dXJlLmNvbS9hcnRpY2xlcy9ubWV0aC4zMDMzKS4KCmBgYHtyfQptYWtlVXBzZXRSIDwtIGZ1bmN0aW9uKGlucHV0X2RmKXsKdmFyX3NpbmdsZSA8LSBpbnB1dF9kZiAKY29scyA8LSBzYXBwbHkodmFyX3NpbmdsZSwgaXMubG9naWNhbCkKdmFyX3NpbmdsZVssY29sc10gPC0gbGFwcGx5KHZhcl9zaW5nbGVbLGNvbHNdLCBhcy5udW1lcmljKQoKdmFyX3NpbmdsZV91cHNldHIgPC0gdmFyX3NpbmdsZSAKdmFyX3NpbmdsZV91cHNldHJbaXMubmEodmFyX3NpbmdsZV91cHNldHIpXSA8LSAwCnZhcl9zaW5nbGVfdXBzZXRyIDwtIGFzLmRhdGEuZnJhbWUodmFyX3NpbmdsZV91cHNldHIpCmZvcihpIGluIDE6bmNvbCh2YXJfc2luZ2xlX3Vwc2V0cikpeyB2YXJfc2luZ2xlX3Vwc2V0clsgLCBpXSA8LSBhcy5pbnRlZ2VyKHZhcl9zaW5nbGVfdXBzZXRyWyAsIGldKSB9CnVwc2V0KHZhcl9zaW5nbGVfdXBzZXRyLCBzZXRzID0gYyhjb2xuYW1lcyh2YXJfc2luZ2xlX3Vwc2V0cikpLCBzZXRzLmJhci5jb2xvciA9ICIjNTZCNEU5IiwKb3JkZXIuYnkgPSAiZnJlcSIsIGtlZXAub3JkZXIgPSBUUlVFKSMsIGVtcHR5LmludGVyc2VjdGlvbnMgPSAib24iLCBrZWVwLm9yZGVyID0gRkFMU0UpCn0KCm1ha2VVcHNldFIoZGZfc2luZ2xlY2FzZXMgJT4lIHNlbGVjdChjb250YWlucyggInN5bXAiKSkgJT4lIHNlbGVjdChjb250YWlucygiYW55IikpKQpgYGAKCiMjIyMgUmVzcGlyYXRvcnkKYGBge3J9Cm1ha2VVcHNldFIoZGZfc2luZ2xlY2FzZXMgJT4lIHNlbGVjdChjb250YWlucygic3ltcCIpKSAlPiUgc2VsZWN0KGNvbnRhaW5zKCJyZXNwIikpICU+JSBzZWxlY3QoLWNvbnRhaW5zKCJhbnkiKSkpCmBgYAoKIyMjIyBDYXJkaW92YXNjdWxhcgpgYGB7cn0KbWFrZVVwc2V0UihkZl9zaW5nbGVjYXNlcyAlPiUgc2VsZWN0KGNvbnRhaW5zKCJzeW1wIikpICU+JSBzZWxlY3QoY29udGFpbnMoImNhcmRpb3Zhc2MiKSkgJT4lIHNlbGVjdCgtY29udGFpbnMoIkxWRUYiKSkgJT4lIHNlbGVjdCgtY29udGFpbnMoImFueSIpKSkKYGBgCgojIyMjIEdJCmBgYHtyfQptYWtlVXBzZXRSKGRmX3NpbmdsZWNhc2VzICU+JSBzZWxlY3QoY29udGFpbnMoInN5bXAiKSkgJT4lIHNlbGVjdChjb250YWlucygiR0kiKSkgJT4lIHNlbGVjdCgtY29udGFpbnMoIm5ldXJvIikpICU+JSBzZWxlY3QoLWNvbnRhaW5zKCJhbnkiKSkpCmBgYAoKIyMjIFNpbmdsZSBjYXNlcyArIGNvaG9ydCB7LnRhYnNldH0KIyMjIyBSZXNwaXJhdG9yeQpgYGB7cn0KYmFyU3ltcCA8LSBmdW5jdGlvbihjb2xuYW1lX2Nob3J0LCBjb2xuYW1lX3NpbmdsZSwgZXhjbHVkZV9zaW5nbGUgPSBOVUxMLCBwbG90dGl0bGUpewoKdmFyX2NvaG9ydCA8LSBkZl9jb2hvcnQgJT4lIAogICAgICAgICAgICAgICAgICAgICAgICBzZWxlY3QoY29udGFpbnMoImNvaG9ydF9pZCIpIHwgY29udGFpbnMoInRvdF9jYXNlc19uIikgfCAoY29udGFpbnMoY29sbmFtZV9jaG9ydCkgJiBjb250YWlucygiX24iKSkpCgp2YXJfY29ob3J0IDwtIHZhcl9jb2hvcnQgJT4lIAogICAgICAgIGdhdGhlcih2YXJpYWJsZSwgdmFsdWUsIDM6bmNvbCh2YXJfY29ob3J0KSkgJT4lIAogICAgICAgIGRyb3BfbmEodmFsdWUpICAlPiUgZ3JvdXBfYnkodmFyaWFibGUpICU+JSAKICAgICAgICBzdW1tYXJpemUocHJjdCA9IHN1bSh2YWx1ZSkvc3VtKHRvdF9jYXNlc19uKSoxMDApCgp2YXJfY29ob3J0IDwtIHNldE5hbWVzKHZhcl9jb2hvcnQkcHJjdCwgdmFyX2NvaG9ydCR2YXJpYWJsZSkKbmFtZXModmFyX2NvaG9ydCkgPC0gc3ViKCJfbiIsICIiLCBuYW1lcyh2YXJfY29ob3J0KSkKCm5fc2luZ2xlIDwtIGRmX3NpbmdsZWNhc2VzICU+JSBucm93KCkKCmlmICghaXMubnVsbChleGNsdWRlX3NpbmdsZSkpewogIHZhcl9zaW5nbGUgPC0gZGZfc2luZ2xlY2FzZXMgJT4lIHNlbGVjdCgtY29udGFpbnMoZXhjbHVkZV9zaW5nbGUpKQogIHZhcl9zaW5nbGUgPC0gdmFyX3NpbmdsZSAlPiUgc2VsZWN0KGNvbnRhaW5zKGNvbG5hbWVfc2luZ2xlKSkKfSBlbHNlCnsKICB2YXJfc2luZ2xlIDwtIGRmX3NpbmdsZWNhc2VzICU+JSBzZWxlY3QoY29udGFpbnMoY29sbmFtZV9zaW5nbGUpKQp9CgogIyU+JSBzZWxlY3QoLWNvbnRhaW5zKCJhbnkiKSkKY29scyA8LSBzYXBwbHkodmFyX3NpbmdsZSwgaXMubG9naWNhbCkKdmFyX3NpbmdsZVssY29sc10gPC0gbGFwcGx5KHZhcl9zaW5nbGVbLGNvbHNdLCBhcy5udW1lcmljKQp2YXJfc2luZ2xlIDwtIGNvbFN1bXModmFyX3NpbmdsZSwgbmEucm0gPSBUUlVFKQp2YXJfc2luZ2xlIDwtIHZhcl9zaW5nbGUvbnJvdyhkZl9zaW5nbGVjYXNlcykqMTAwCgpiYXJfZGZfcHJjdCA8LSBkYXRhLmZyYW1lKAogIHggPSBjKG5hbWVzKHZhcl9zaW5nbGUpLCBuYW1lcyh2YXJfY29ob3J0KSksCiAgdmFscyA9IGModmFyX3NpbmdsZSwgdmFyX2NvaG9ydCksCiAgY29sID0gYyhyZXAoInNpbmdsZSIsIGxlbmd0aCh2YXJfc2luZ2xlKSksIHJlcCgiY29ob3J0cyIsIGxlbmd0aCh2YXJfY29ob3J0KSkpCikKCnBfcHJjdCA8LSBnZ3Bsb3QoYmFyX2RmX3ByY3QsIGFlcyh4ID0geCwgeSA9ICB2YWxzLCBmaWxsID0gY29sKSkgKwogICAgZ2VvbV9iYXIoc3RhdCA9ICJpZGVudGl0eSIsIHBvc2l0aW9uID0gImRvZGdlIikgKwogICAgdGhlbWVfYncoKSArIAogICAgbGFicyh0aXRsZSA9IHBsb3R0aXRsZSwgCiAgICAgICAgICBzdWJ0aXRsZSA9ICJQZXJjZW50IG9mIGdyb3VwIiwgeCA9ICJ0cmVhdG1lbnQiLCB5ID0gIiUiLCBjb2wgPSAiICIpICArIAogICAgICAgICAgdGhlbWUoYXhpcy50ZXh0Lng9ZWxlbWVudF90ZXh0KGFuZ2xlPTkwLCBoanVzdD0xKSkrCiAgICAgICAgICBzY2FsZV9maWxsX21hbnVhbCh2YWx1ZXMgPSB3ZXNfcGFsZXR0ZSgiUm95YWwxIikpCnBfcHJjdAp9CgptYWtlSGVhdG1hcF9jb2hvcnQoInN5bXBfcmVzcCIsICJzeW1wX3Jlc3AiLCBwbG90dGl0bGUgPSAiQ2FzZXMgd2l0aCByZXNwaXJhdG9yeSBzeW1wdG9tcywgcGVyIGNvaG9ydCIpCgpiYXJTeW1wKCJzeW1wX3Jlc3AiLCAic3ltcF9yZXNwIiwgcGxvdHRpdGxlID0gIkNhc2VzIHdpdGggcmVzcGlyYXRvcnkgc3ltcHRvbXMiKQpgYGAKCgpgYGB7cn0KIyB2YXJfY29ob3J0IDwtIGRmX2NvaG9ydCAlPiUgc2VsZWN0KCgiY29ob3J0X2lkIikgfCAidG90X2Nhc2VzX24iIHwoIGNvbnRhaW5zKCJzeW1wX3Jlc3AiKSAmIGNvbnRhaW5zKCJuIikpKQojIAojIHJlc3Bfc3ltcF9jb2hvcnQgPC0gdmFyX2NvaG9ydCAlPiUgCiMgICBnYXRoZXIodmFyaWFibGUsIHZhbHVlLCAzOm5jb2wodmFyX2NvaG9ydCkpICU+JSBncm91cF9ieShjb2hvcnRfaWQsIHZhcmlhYmxlKSAlPiUgc3VtbWFyaXplKHByY3QgPSB2YWx1ZS90b3RfY2FzZXNfbikKIyAKIyBnZ3Bsb3QocmVzcF9zeW1wX2NvaG9ydCwgYWVzKHggPSBwcmN0LCB5ID0gY29ob3J0X2lkLCBjb2wgPSB2YXJpYWJsZSkpICsgZ2VvbV9wb2ludCgpCmBgYAoKIyMjIyBDYXJkaW92YXNjdWxhcgpgYGB7cn0KbWFrZUhlYXRtYXBfY29ob3J0KCJzeW1wX2NhcmRpb3Zhc2MiLCAic3ltcF9jYXJkaW92YXNjIiwgZXhjbHVkZV9zaW5nbGUgPSAic3ltcF9jYXJkaW92YXNjX0xWRUYiLCBwbG90dGl0bGUgPSAiQ2FzZXMgd2l0aCBjYXJkaW92YXNjdWxhciBzeW1wdG9tcywgcGVyIGNvaG9ydCIpCgpiYXJTeW1wKCJzeW1wX2NhcmRpb3Zhc2MiLCAic3ltcF9jYXJkaW92YXNjIiwgZXhjbHVkZV9zaW5nbGUgPSAic3ltcF9jYXJkaW92YXNjX0xWRUYiLCBwbG90dGl0bGUgPSAiQ2FzZXMgd2l0aCBjYXJkaW92YXNjdWxhciBzeW1wdG9tcyIpCmBgYAoKIyMjIyBHYXN0cm8taW50ZXN0aW5hbApgYGB7cn0KbWFrZUhlYXRtYXBfY29ob3J0KCJzeW1wX0dJIiwgInN5bXBfR0kiLCBwbG90dGl0bGUgPSAiQ2FzZXMgd2l0aCBHSSBzeW1wdG9tcywgcGVyIGNvaG9ydCIpCgpiYXJTeW1wKCJzeW1wX0dJIiwgInN5bXBfR0kiLCBwbG90dGl0bGUgPSAiQ2FzZXMgd2l0aCBHSSBzeW1wdG9tcyIpCmBgYAoKIyMgQ09WSUQgY29udGFjdApgYGB7cn0KdmFyX2NvaG9ydCA8LSBkZl9jb2hvcnQgJT4lIHNlbGVjdCgoImNvaG9ydF9pZCIgfCAidG90X2Nhc2VzX24iKSB8ICggY29udGFpbnMoImNvdmlkIikgJiBjb250YWlucygiX24iKSAmIChjb250YWlucygicG9zIikgfCBjb250YWlucygiY2xvc2Vjb250IikgIHwgY29udGFpbnMoImFueSIpKSkpCnZhcl9jb2hvcnQkY29ob3J0X2lkIDwtIHBhc3RlMCh2YXJfY29ob3J0JGNvaG9ydF9pZCwgIiAobiA9ICIsIGFzLmNoYXJhY3Rlcih2YXJfY29ob3J0JHRvdF9jYXNlc19uKSwiKSIpCgp2YXJfY29ob3J0IDwtIHZhcl9jb2hvcnQgJT4lIAogIGdhdGhlcih2YXJpYWJsZSwgdmFsdWUsIDM6bmNvbCh2YXJfY29ob3J0KSkgJT4lIGdyb3VwX2J5KGNvaG9ydF9pZCwgdmFyaWFibGUpICU+JSBzdW1tYXJpemUocHJjdCA9IHZhbHVlL3RvdF9jYXNlc19uKjEwMCkKCnZhcl9jb2hvcnQkdmFyaWFibGUgPC0gc3ViKCJuXyIsICIiLCB2YXJfY29ob3J0JHZhcmlhYmxlKQoKdmFyX3NpbmdsZSA8LSBkZl9zaW5nbGVjYXNlcyAlPiUgc2VsZWN0KGNvbnRhaW5zKCJjb3ZpZCIpKQpjb2xzIDwtIHNhcHBseSh2YXJfc2luZ2xlLCBpcy5sb2dpY2FsKQp2YXJfc2luZ2xlWyxjb2xzXSA8LSBsYXBwbHkodmFyX3NpbmdsZVssY29sc10sIGFzLm51bWVyaWMpCnZhcl9zaW5nbGUgPC0gY29sU3Vtcyh2YXJfc2luZ2xlLCBuYS5ybSA9IFRSVUUpCnZhcl9zaW5nbGUgPC0gdmFyX3NpbmdsZS9ucm93KGRmX3NpbmdsZWNhc2VzKSoxMDAKdmFyX3NpbmdsZSA8LSBhcy5kYXRhLmZyYW1lKHZhcl9zaW5nbGUpICU+JSByb3duYW1lc190b19jb2x1bW4oKQp2YXJfc2luZ2xlJGNvaG9ydF9pZCA8LSBwYXN0ZTAoInNpbmdsZSBjYXNlcyAobiA9ICIsIG5fc2luZ2xlX2Nhc2VzLCIpIikKY29sbmFtZXModmFyX3NpbmdsZSkgPC0gYygidmFyaWFibGUiLCAicHJjdCIsICJjb2hvcnRfaWQiKQoKCm1pc3NpbmcgPC0gc2V0ZGlmZih2YXJfc2luZ2xlJHZhcmlhYmxlLCB2YXJfY29ob3J0JHZhcmlhYmxlKQppZiAobGVuZ3RoKG1pc3NpbmcpICE9IDAgKXsKICBtaXNzaW5nX2RmIDwtIGRhdGEuZnJhbWUodmFyaWFibGUgPSBtaXNzaW5nLCBwcmN0ID0gcmVwKE5BLCBsZW5ndGgobWlzc2luZykpLCBjb2hvcnRfaWQgPSByZXAodW5pcXVlKHZhcl9jb2hvcnQkY29ob3J0X2lkKSwgbGVuZ3RoKG1pc3NpbmcpKSkKICB2YXJfY29ob3J0IDwtIGJpbmRfcm93cyh2YXJfY29ob3J0LCBhc190aWJibGUobWlzc2luZ19kZikpCn0gCgptaXNzaW5nIDwtIHNldGRpZmYodmFyX2NvaG9ydCR2YXJpYWJsZSwgdmFyX3NpbmdsZSR2YXJpYWJsZSkKCmlmIChsZW5ndGgobWlzc2luZykgIT0gMCkgewogIGlmIChsZW5ndGgobWlzc2luZykgIT0gMCl7CmRhdGEuZnJhbWUodmFyaWFibGUgPSBtaXNzaW5nLCBwcmN0ID0gcmVwKE5BLCBsZW5ndGgobWlzc2luZykpLCBjb2hvcnRfaWQgPSByZXAodW5pcXVlKHZhcl9zaW5nbGUkY29ob3J0X2lkKSwgbGVuZ3RoKG1pc3NpbmcpKSkKICB2YXJfc2luZ2xlIDwtIGJpbmRfcm93cyh2YXJfc2luZ2xlLCBhc190aWJibGUobWlzc2luZ19kZikpCiAgfQp9CgoKaG1fY29ob3J0IDwtIGdncGxvdCh2YXJfY29ob3J0LCBhZXMoeCA9IHZhcmlhYmxlLCB5ID0gY29ob3J0X2lkLCBmaWxsID0gcHJjdCkpICsgCiAgICBnZW9tX3RpbGUoKSArIHRoZW1lX2NsYXNzaWMoKSArCiAgICB0aGVtZShheGlzLnRleHQueD1lbGVtZW50X2JsYW5rKCksIGF4aXMudGlja3MueD1lbGVtZW50X2JsYW5rKCksIGF4aXMubGluZT1lbGVtZW50X2JsYW5rKCkpKwogICBzY2FsZV9maWxsX2dyYWRpZW50KGxvdyA9ICJ5ZWxsb3ciLCBoaWdoPSJyZWQiLCBuYS52YWx1ZSA9ICJsaWdodGdyYXkiLCBsaW1pdHMgPSBjKDAsMTAwKSkgKwogICAgbGFicyh4ID0gIiIsIHkgPSAiY29ob3J0IiwgdGl0bGUgPSAiQ09WSUQgc3ltcHRvbXMsIHBlciBjb2hvcnQiKSArCiAgICBnZW9tX3RleHQoYWVzKGxhYmVsPXJvdW5kKHByY3QsIDIpKSwgc2l6ZSA9IDMsIGNvbG9yID0gImJsYWNrIikKCmhtX3NpbmdsZSA8LSBnZ3Bsb3QodmFyX3NpbmdsZSwgYWVzKHggPSB2YXJpYWJsZSwgeSA9IGNvaG9ydF9pZCwgZmlsbCA9IHByY3QpKSArIAogICAgZ2VvbV90aWxlKCkgKyAgdGhlbWVfY2xhc3NpYygpICsKICAgIHRoZW1lKGF4aXMudGV4dC54PWVsZW1lbnRfdGV4dChhbmdsZT05MCwgaGp1c3Q9MSksIGF4aXMubGluZT1lbGVtZW50X2JsYW5rKCkpKwogICAgc2NhbGVfZmlsbF9ncmFkaWVudChsb3cgPSAieWVsbG93IiwgaGlnaCA9ICJyZWQiLCBuYS52YWx1ZSA9ICJsaWdodGdyYXkiLCBsaW1pdHMgPSBjKDAsMTAwKSkrIGxhYnMoeSA9ICJjb2hvcnQiKSArCiAgICBnZW9tX3RleHQoYWVzKGxhYmVsPXJvdW5kKHByY3QsIDIpKSwgc2l6ZSA9IDMsIGNvbG9yID0gImJsYWNrIikgCgpwbG90X2dyaWQoaG1fY29ob3J0LCBobV9zaW5nbGUsIGFsaWduID0gInYiLCBucm93ID0gMiwgcmVsX2hlaWdodHMgPSBjKDEvMiwgMS8yKSkKCmBgYAoKYGBge3J9CnZhcl9jb2hvcnQgPC0gZGZfY29ob3J0ICU+JSAKICAgICAgICAgICAgICAgICAgICAgICAgc2VsZWN0KGNvbnRhaW5zKCJjb2hvcnRfaWQiKSB8IGNvbnRhaW5zKCJ0b3RfY2FzZXNfbiIpIHwgY29udGFpbnMoImNvdmlkIikgJiBjb250YWlucygiX24iKSAmIChjb250YWlucygiX3BvcyIpIHwgY29udGFpbnMoImNsb3NlIikpKQoKY292aWRfY29ob3J0IDwtIHZhcl9jb2hvcnQgJT4lIAogICAgICAgIGdhdGhlcih2YXJpYWJsZSwgdmFsdWUsIDM6bmNvbCh2YXJfY29ob3J0KSkgJT4lIAogICAgICAgIGRyb3BfbmEodmFsdWUpICAlPiUgZ3JvdXBfYnkodmFyaWFibGUpICU+JSAKICAgICAgICBzdW1tYXJpemUocHJjdCA9IHN1bSh2YWx1ZSkvc3VtKHRvdF9jYXNlc19uKSoxMDApCgpjb3ZpZF9jb2hvcnQgPC0gc2V0TmFtZXMoY292aWRfY29ob3J0JHByY3QsIGNvdmlkX2NvaG9ydCR2YXJpYWJsZSkKCm5fc2luZ2xlIDwtIGRmX3NpbmdsZWNhc2VzICU+JSBucm93KCkKdmFyX3NpbmdsZSA8LSBkZl9zaW5nbGVjYXNlcyAlPiUgc2VsZWN0KGNvbnRhaW5zKCJjb3ZpZCIpKSAKY29scyA8LSBzYXBwbHkodmFyX3NpbmdsZSwgaXMubG9naWNhbCkKdmFyX3NpbmdsZVssY29sc10gPC0gbGFwcGx5KHZhcl9zaW5nbGVbLGNvbHNdLCBhcy5udW1lcmljKQoKbWFrZVVwc2V0UihkZl9zaW5nbGVjYXNlcyAlPiUgc2VsZWN0KGNvbnRhaW5zKCJjb3ZpZCIpKSAlPiUgc2VsZWN0KC1jb250YWlucygiY292aWRfSWdNX3BvcyIpKSAlPiUgc2VsZWN0KC1jb250YWlucygiY292aWRfSWdBX3BvcyIpKSAgJT4lIHNlbGVjdCgtY29udGFpbnMoImNvdmlkX0lnR19wb3MiKSkgICU+JSBzZWxlY3QoLWNvbnRhaW5zKCJjb3ZpZF9zZXJvX3BvcyIpKSApCgp2YXJfc2luZ2xlIDwtIGNvbFN1bXModmFyX3NpbmdsZSwgbmEucm0gPSBUUlVFKQp2YXJfc2luZ2xlIDwtIHZhcl9zaW5nbGUvbnJvdyhkZl9zaW5nbGVjYXNlcykqMTAwCgpiYXJfZGZfcHJjdCA8LSBkYXRhLmZyYW1lKAogIHggPSBjKCJjbG9zZSBjb250YWN0IHJlcG9ydGVkIiwgIlBDUiArIiwgInN0b29sICsiLCJQQ1Igb3Igc3Rvb2wgb3Igc2VybyArIiwgImFueSBzZXJvbG9neSArIiwgInNlcm8gKyBmdXJ0aGVyIE5TIiwgIklnQSArIiwgIklnTSArIiwgIklnRyArIiwgImNsb3NlIGNvbnRhY3QgcmVwb3J0ZWQiLCAiSWdBICsiLCAiSWdHICsiLCAiSWdNICsiLCAiUENSICsiLCAic2VybyArIGZ1cnRoZXIgTlMiLCAic3Rvb2wgKyIpLAogIHZhbHMgPSBjKHZhcl9zaW5nbGUsIGNvdmlkX2NvaG9ydCksCiAgY29sID0gYyhyZXAoInNpbmdsZSIsIGxlbmd0aCh2YXJfc2luZ2xlKSksIHJlcCgiY29ob3J0cyIsIGxlbmd0aChjb3ZpZF9jb2hvcnQpKSkKKQoKcF9wcmN0IDwtIGdncGxvdChiYXJfZGZfcHJjdCwgYWVzKHggPSB4LCB5ID0gIHZhbHMsIGZpbGwgPSBjb2wpKSArCiAgICBnZW9tX2JhcihzdGF0ID0gImlkZW50aXR5IiwgcG9zaXRpb24gPSAiZG9kZ2UiKSArCiAgICB0aGVtZV9idygpICsgCiAgICBsYWJzKHRpdGxlID0gIlNBUlMtQ29WMiB0ZXN0aW5nIiwgCiAgICAgICAgIHN1YnRpdGxlID0gIlByY3QiLCB4ID0gInZhcmlhYmxlIiwgeSA9ICIlIiwgY29sID0gIiAiKSArCiAgICB0aGVtZShheGlzLnRleHQueD1lbGVtZW50X3RleHQoYW5nbGU9OTAsIGhqdXN0PTEpKSArCiAgICBzY2FsZV9maWxsX21hbnVhbCh2YWx1ZXMgPSB3ZXNfcGFsZXR0ZSgiUm95YWwxIikpCiNwX3ByY3QKCm5laXRoZXJfUENSX0lnIDwtIG5yb3coZGZfc2luZ2xlY2FzZXMgJT4lIGZpbHRlcigoY292aWRfc2Vyb19hbnkgPT0gRkFMU0UgfCBpcy5uYShjb3ZpZF9zZXJvX2FueSkpICYgKGNvdmlkX1BDUl9wb3MgPT0gRkFMU0UgfCBpcy5uYShjb3ZpZF9QQ1JfcG9zKSkgJiAoY292aWRfUENSX3N0b29sX3BvcyA9PSBGQUxTRSB8IGlzLm5hKGNvdmlkX1BDUl9zdG9vbF9wb3MpKSkpCgpuZWl0aGVyX1BDUl9JZ19jbG9zZWNvbnRhY3QgPC0KICBucm93KGRmX3NpbmdsZWNhc2VzICU+JSBmaWx0ZXIoKGNvdmlkX3Nlcm9fYW55ID09IEZBTFNFIHwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaXMubmEoY292aWRfc2Vyb19hbnkpKSAmCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKGNvdmlkX1BDUl9wb3MgPT0gRkFMU0UgfAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlzLm5hKGNvdmlkX1BDUl9wb3MpKSAmCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKGNvdmlkX1BDUl9zdG9vbF9wb3MgPT0gRkFMU0UgfAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlzLm5hKGNvdmlkX1BDUl9zdG9vbF9wb3MpKSAmCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKGNvdmlkX2Nsb3NlY29udGFjdCA9PSBGQUxTRSB8IGlzLm5hKGNvdmlkX2Nsb3NlY29udGFjdCkpCiAgKSkKCnByaW50KHBhc3RlMCgiQ2FzZXMgd2l0aCBuZWl0aGVyIFBDUiBub3Igc2Vyb2xvZ3k6ICIsIG5laXRoZXJfUENSX0lnKSkKCnByaW50KHBhc3RlMCgiQ2FzZXMgd2l0aCBuZWl0aGVyIFBDUiBub3Igc2Vyb2xvZ3kgbm9yIGNsb3NlY29udGFjdDogIiwgbmVpdGhlcl9QQ1JfSWdfY2xvc2Vjb250YWN0KSkKYGBgCgojIyBLYXdhc2FraSBjcml0ZXJpYQoKYGBge3J9Cm1ha2VIZWF0bWFwX2NvaG9ydCgia2F3YXNha2kiLCAia2F3YXNha2kiLGV4Y2x1ZGVfc2luZ2xlID0gImtveW9iYXMiLCBwbG90dGl0bGUgPSAiQ2FzZXMgd2l0aCBrYXdhc2FraSBzeW1wdG9tcywgcGVyIGNvaG9ydCIpCgpiYXJTeW1wKCJrYXdhc2FraSIsICJrYXdhc2FraSIsIGV4Y2x1ZGVfc2luZ2xlID0gImtveW9iYXMiLCBwbG90dGl0bGUgPSAiS2F3YXNha2kgc3ltcHRvbXMiKQpgYGAKCiMjIFNob2NrCmBgYHtyfQptYWtlQmFycGxvdCgic3ltcF9jYXJkaW92YXNjX3Nob2NrX24iLCAic3ltcF9jYXJkaW92YXNjX3Nob2NrIiwgIlNob2NrIikKYGBgCgojIyBMYWIgdmFsdWVzIHsudGFic2V0fQpGb3IgbGFiIHZhbHVlcywgc29tZXRpbWVzIG11bHRpcGxlIHZhbHVlcyBhcmUgcmVwb3J0ZWQgKGJhc2VsaW5lLCBwZWFrIG9yIG5vdC1zcGVjaWZpZWQpLiBBbGwgbGFiIHZhbHVlcyBhcmUgY29sbGFwc2VkIGJhc2VkIG9uIHRoZSBtYXggKG9yIHRoZSBtaW4gZm9yIGUuZy4gaGVtb2dsb2Jpbik6IHNvIG9ubHkgdGhlIGhpZ2hlc3QgdmFsdWUgb2YgbWVkaWFuLCBRMSBvciBRMyBpcyB1c2VkLiBEYXNoZWQgdmVydGljYWwgbGluZSBjb3JyZXNwb25kcyB0byB0aGUgY3V0b2ZmIHVzZWQgaW4gdGhlIHN0dWR5LiAKCiMjIyBDLXJlYWN0aXZlIHByb3RlaW4KCmBgYHtyfQpjcnBfY29sbGFwc2VfY29ob3J0IDwtIGNvbGxhcHNlX2xhYnZhbHNfY29ob3J0KGRmX2NvaG9ydF9jb250cm9scywgIm1heCIsICJDUlAiKQpjcnBfY29sbGFwc2Vfc2luZ2xlIDwtIGNvbGxhcHNlX2xhYnZhbHNfc2luZ2xlKGRmX3NpbmdsZWNhc2VzLCAibWF4IiwgIkNSUCIpCmNycF9taXNzaW5nIDwtIHN1bShpcy5uYShjcnBfY29sbGFwc2Vfc2luZ2xlJENSUF9tYXgpKQoKcF9jcnBfY29ob3J0IDwtIGdncGxvdChjcnBfY29sbGFwc2VfY29ob3J0LCBhZXMoeSA9IGNvaG9ydF9pZCwgeCA9IENSUF9tZWQsIGNvbCA9IGNvaG9ydF90eXBlKSkgKyAKICAgICAgICBnZW9tX3BvaW50KCkgKyAgCiAgICAgICAgZ2VvbV9lcnJvcmJhcihhZXMoeG1pbj1DUlBfbWluLCB4bWF4PUNSUF9tYXgpLCB3aWR0aD0uMiwgcG9zaXRpb249cG9zaXRpb25fZG9kZ2UoLjkpKSArIGxpbXMoeCA9IGMoMCw2MDApKSArIAogICAgICAgIHRoZW1lX2J3KCkgKyBsYWJzKHRpdGxlID0gIkNSUCIsIHkgPSAiY29ob3J0IiwgeCA9ICIiKSArCiAgICAgICAgZ2VvbV92bGluZSh4aW50ZXJjZXB0ID0gY29fQ1JQLCBsaW5ldHlwZSA9ICJkYXNoZWQiLCBjb2xvciA9ICJibGFjayIpICsgdGhlbWUobGVnZW5kLmp1c3RpZmljYXRpb24gPSBjKDEsIDEpLCBsZWdlbmQucG9zaXRpb24gPSBjKDAuOTgsIDAuOTgpLCBsZWdlbmQudGl0bGU9ZWxlbWVudF9ibGFuaygpKSArCiAgICAgICAgc2NhbGVfY29sb3JfbWFudWFsKHZhbHVlcyA9IHdlc19wYWxldHRlKCJSb3lhbDEiKSkKCnBfY3JwX3NpbmdsZSA8LSBnZ3Bsb3QoY3JwX2NvbGxhcHNlX3NpbmdsZSwgYWVzKHggPSBhcy5udW1lcmljKENSUF9tYXgpLCB5ID0gY29ob3J0X2lkKSkgKwogICAgICBnZW9tX3Zpb2xpbihmaWxsID0gd2VzX3BhbGV0dGUoIkRhcmplZWxpbmcyIilbNF0pICsgCiAgICAgIGdlb21fYm94cGxvdCh3aWR0aD0uMywgZmlsbCA9ICB3ZXNfcGFsZXR0ZSgiRGFyamVlbGluZzIiKVsxXSkgKyAKICAgICAgdGhlbWVfYncoKSArIGdlb21fYmVlc3dhcm0oZ3JvdXBPblg9RkFMU0UsIGFscGhhID0gMC41KSArIGxpbXMoeCA9IGMoMCw2MDApKSArIGxhYnMoeSA9ICIiLCB4ID0gIkNSUCAobWcvZEwpIiwgc3VidGl0bGUgPSBwYXN0ZTAoIm1pc3NpbmcgZGF0YSBmb3IgIiwgY3JwX21pc3NpbmcsICIgY2FzZXMiKSkgKwogICAgICBnZW9tX2hsaW5lKHlpbnRlcmNlcHQgPSBjb19DUlAsIGxpbmV0eXBlID0gImRhc2hlZCIsIGNvbG9yID0gImJsYWNrIikKCkNSUF9ncmlkIDwtIHBsb3RfZ3JpZChwX2NycF9jb2hvcnQsIHBfY3JwX3NpbmdsZSwgYWxpZ24gPSAidiIsIG5yb3cgPSAyLCByZWxfaGVpZ2h0cyA9IGMoMi8zLCAxLzMpKQpDUlBfZ3JpZApgYGAKCiMjIyBMeW1waG9jeXRlcwpgYGB7cn0KbHltcGhvX2NvbGxhcHNlX2NvaG9ydCA8LSBjb2xsYXBzZV9sYWJ2YWxzX2NvaG9ydChkZl9jb2hvcnRfY29udHJvbHMsICJtaW4iLCAibHltcGhvIikKbHltcGhvX2NvbGxhcHNlX3NpbmdsZSA8LSBjb2xsYXBzZV9sYWJ2YWxzX3NpbmdsZShkZl9zaW5nbGVjYXNlcywgIm1pbiIsICJseW1waG8iKQpseW1waG9fbWlzc2luZyA8LSBzdW0oaXMubmEobHltcGhvX2NvbGxhcHNlX3NpbmdsZSRseW1waG9fbWluKSkKCnBfbHltcGhvX2NvaG9ydCA8LSBnZ3Bsb3QobHltcGhvX2NvbGxhcHNlX2NvaG9ydCwgYWVzKHkgPSBjb2hvcnRfaWQsIHggPSBseW1waG9fbWVkLCBjb2wgPSBjb2hvcnRfdHlwZSkpICsgCiAgICAgICAgZ2VvbV9wb2ludCgpICsgIAogICAgICAgIGdlb21fZXJyb3JiYXIoYWVzKHhtaW49bHltcGhvX21pbiwgeG1heD1seW1waG9fbWF4KSwgd2lkdGg9LjIsIHBvc2l0aW9uPXBvc2l0aW9uX2RvZGdlKC45KSkgKyAKICAgICAgICB0aGVtZV9idygpICsgbGFicyh0aXRsZSA9ICJseW1waG9jeXRlcyIsIHkgPSAiIiwgeCA9ICIiKSArIGxpbXMoeCA9IGMoMCw3NTAwKSkgICsKICAgICAgICAgZ2VvbV92bGluZSh4aW50ZXJjZXB0ID0gY29fbHltcGhvLCBsaW5ldHlwZSA9ICJkYXNoZWQiLCBjb2xvciA9ICJibGFjayIpICsgdGhlbWUobGVnZW5kLmp1c3RpZmljYXRpb24gPSBjKDEsIDEpLCBsZWdlbmQucG9zaXRpb24gPSBjKDAuOTgsIDAuOTgpLCBsZWdlbmQudGl0bGU9ZWxlbWVudF9ibGFuaygpKSArCiAgICAgICAgc2NhbGVfY29sb3JfbWFudWFsKHZhbHVlcyA9IHdlc19wYWxldHRlKCJSb3lhbDEiKSkjKwogICAgICAgICNycmVtb3ZlKCJ5LnRleHQiKSAKCnBfbHltcGhvX3NpbmdsZSA8LSBnZ3Bsb3QobHltcGhvX2NvbGxhcHNlX3NpbmdsZSwgYWVzKHggPSBhcy5udW1lcmljKGx5bXBob19taW4pLCB5ID0gY29ob3J0X2lkKSkgKwogICAgICBnZW9tX3Zpb2xpbihmaWxsID0gd2VzX3BhbGV0dGUoIkRhcmplZWxpbmcyIilbNF0pICsgCiAgICAgIGdlb21fYm94cGxvdCh3aWR0aD0uMywgZmlsbCA9IHdlc19wYWxldHRlKCJEYXJqZWVsaW5nMiIpWzFdKSArIAogICAgICBsaW1zKHggPSBjKDAsNzUwMCkpKwogICAgICB0aGVtZV9idygpICsgZ2VvbV9iZWVzd2FybShncm91cE9uWD1GQUxTRSwgYWxwaGEgPSAwLjUpICArIGxhYnMoeSA9ICIiLCB4ID0gIkx5bXBob2N5dGVzICgvwrVMKSIsIHN1YnRpdGxlID0gcGFzdGUwKCJtaXNzaW5nIGRhdGEgZm9yICIsIGx5bXBob19taXNzaW5nLCAiIGNhc2VzIikpICsKICAgICAgZ2VvbV92bGluZSh4aW50ZXJjZXB0ID0gY29fbHltcGhvLCBsaW5ldHlwZSA9ICJkYXNoZWQiLCBjb2xvciA9ICJibGFjayIpICMrIAogICAgICAjcnJlbW92ZSgieS50ZXh0IikgCgpseW1waG9fZ3JpZCA8LSBwbG90X2dyaWQocF9seW1waG9fY29ob3J0LCBwX2x5bXBob19zaW5nbGUsIGFsaWduID0gInYiLCBucm93ID0gMiwgcmVsX2hlaWdodHMgPSBjKDIvMywgMS8zKSkKbHltcGhvX2dyaWQKYGBgCgojIyMgV2hpdGUgYmxvb2QgY2VsbHMKYGBge3J9CndiY19jb2xsYXBzZV9jb2hvcnQgPC0gY29sbGFwc2VfbGFidmFsc19jb2hvcnQoZGZfY29ob3J0X2NvbnRyb2xzLCAibWF4IiwgIldCQyIpCndiY19jb2xsYXBzZV9zaW5nbGUgPC0gY29sbGFwc2VfbGFidmFsc19zaW5nbGUoZGZfc2luZ2xlY2FzZXMsICJtYXgiLCAiV0JDIikKd2JjX21pc3NpbmcgPC0gc3VtKGlzLm5hKHdiY19jb2xsYXBzZV9zaW5nbGUkV0JDX21heCkpCgpwX3diY19jb2hvcnQgPC0gZ2dwbG90KHdiY19jb2xsYXBzZV9jb2hvcnQsIGFlcyh5ID0gY29ob3J0X2lkLCB4ID0gV0JDX21lZCwgY29sID0gY29ob3J0X3R5cGUpKSArIAogICAgICAgIGdlb21fcG9pbnQoKSArICAKICAgICAgICBnZW9tX2Vycm9yYmFyKGFlcyh4bWluPVdCQ19taW4sIHhtYXg9V0JDX21heCksIHdpZHRoPS4yLCBwb3NpdGlvbj1wb3NpdGlvbl9kb2RnZSguOSkpICsgbGltcyh4ID0gYygwLDUwMDAwKSkgKyAKICAgICAgICB0aGVtZV9idygpICsgbGFicyh0aXRsZSA9ICJXQkMiLCB5ID0gImNvaG9ydCIsIHggPSAiIikgICsKICAgICAgICBnZW9tX3ZsaW5lKHhpbnRlcmNlcHQgPSBjb19XQkMsIGxpbmV0eXBlID0gImRhc2hlZCIsIGNvbG9yID0gImJsYWNrIikgICsgdGhlbWUobGVnZW5kLmp1c3RpZmljYXRpb24gPSBjKDEsIDEpLCBsZWdlbmQucG9zaXRpb24gPSBjKDAuOTgsIDAuOTgpLCBsZWdlbmQudGl0bGU9ZWxlbWVudF9ibGFuaygpKSArCiAgICAgICAgc2NhbGVfY29sb3JfbWFudWFsKHZhbHVlcyA9IHdlc19wYWxldHRlKCJSb3lhbDEiKSkKCnBfd2JjX3NpbmdsZSA8LSBnZ3Bsb3Qod2JjX2NvbGxhcHNlX3NpbmdsZSwgYWVzKHggPSBhcy5udW1lcmljKFdCQ19tYXgpLCB5ID0gY29ob3J0X2lkKSkgKwogICAgICBnZW9tX3Zpb2xpbihmaWxsID0gd2VzX3BhbGV0dGUoIkRhcmplZWxpbmcyIilbNF0pICsgCiAgICAgIGdlb21fYm94cGxvdCh3aWR0aD0uMywgZmlsbCA9IHdlc19wYWxldHRlKCJEYXJqZWVsaW5nMiIpWzFdKSArIAogICAgICB0aGVtZV9idygpICsgZ2VvbV9iZWVzd2FybShncm91cE9uWD1GQUxTRSwgYWxwaGEgPSAwLjUpICsgbGFicyh5ID0gIiIsIHggPSAiV0JDICgvwrVMKSIsIHN1YnRpdGxlID0gcGFzdGUwKCJtaXNzaW5nIGRhdGEgZm9yICIsIHdiY19taXNzaW5nLCAiIGNhc2VzIikpICsgbGltcyh4ID0gYygwLDUwMDAwKSkgKwogICAgICBnZW9tX3ZsaW5lKHhpbnRlcmNlcHQgPSBjb19XQkMsIGxpbmV0eXBlID0gImRhc2hlZCIsIGNvbG9yID0gImJsYWNrIikgCgpXQkNfZ3JpZCA8LSBwbG90X2dyaWQocF93YmNfY29ob3J0LCBwX3diY19zaW5nbGUsIGFsaWduID0gInYiLCBucm93ID0gMiwgcmVsX2hlaWdodHMgPSBjKDIvMywgMS8zKSkKV0JDX2dyaWQKYGBgCgoKIyMjIEZlcnJpdGluCmBgYHtyfQpmZXJyaXRpbl9jb2xsYXBzZV9jb2hvcnQgPC0gY29sbGFwc2VfbGFidmFsc19jb2hvcnQoZGZfY29ob3J0X2NvbnRyb2xzLCAibWF4IiwgImZlcnJpdCIpCmZlcnJpdGluX2NvbGxhcHNlX3NpbmdsZSA8LSBjb2xsYXBzZV9sYWJ2YWxzX3NpbmdsZShkZl9zaW5nbGVjYXNlcywgIm1heCIsICJmZXJyaXQiKQpmZXJyaXRpbl9taXNzaW5nIDwtIHN1bShpcy5uYShmZXJyaXRpbl9jb2xsYXBzZV9zaW5nbGUkZmVycml0X21heCkpCgpwX2ZlcnJpdGluX2NvaG9ydCA8LSBnZ3Bsb3QoZmVycml0aW5fY29sbGFwc2VfY29ob3J0LCBhZXMoeSA9IGNvaG9ydF9pZCwgeCA9IGZlcnJpdF9tZWQsIGNvbCA9IGNvaG9ydF90eXBlKSkgKyAKICAgICAgICBnZW9tX3BvaW50KCkgKyAgCiAgICAgICAgZ2VvbV9lcnJvcmJhcihhZXMoeG1pbj1mZXJyaXRfbWluLCB4bWF4PWZlcnJpdF9tYXgpLCB3aWR0aD0uMiwgcG9zaXRpb249cG9zaXRpb25fZG9kZ2UoLjkpKSArIGxpbXMoeCA9IGMoMCwxMTAwMCkpICsgCiAgICAgICAgdGhlbWVfYncoKSArIGxhYnModGl0bGUgPSAiRmVycml0aW4iLCB5ID0gImNvaG9ydCIsIHggPSAiIikgKwogICAgICAgIGdlb21fdmxpbmUoeGludGVyY2VwdCA9IGNvX2ZlcnJpdGluLCBsaW5ldHlwZSA9ICJkYXNoZWQiLCBjb2xvciA9ICJibGFjayIpICsgdGhlbWUobGVnZW5kLmp1c3RpZmljYXRpb24gPSBjKDEsIDEpLCBsZWdlbmQucG9zaXRpb24gPSBjKDAuOTgsIDAuOTgpLCBsZWdlbmQudGl0bGU9ZWxlbWVudF9ibGFuaygpKSArCiAgICAgICAgc2NhbGVfY29sb3JfbWFudWFsKHZhbHVlcyA9IHdlc19wYWxldHRlKCJSb3lhbDEiKSkKCnBfZmVycml0aW5fc2luZ2xlIDwtIGdncGxvdChmZXJyaXRpbl9jb2xsYXBzZV9zaW5nbGUsIGFlcyh4ID0gYXMubnVtZXJpYyhmZXJyaXRfbWF4KSwgeSA9IGNvaG9ydF9pZCkpICsKICAgICAgZ2VvbV92aW9saW4oZmlsbCA9IHdlc19wYWxldHRlKCJEYXJqZWVsaW5nMiIpWzRdKSArIAogICAgICBnZW9tX2JveHBsb3Qod2lkdGg9LjMsIGZpbGwgPSB3ZXNfcGFsZXR0ZSgiRGFyamVlbGluZzIiKVsxXSkgKyAKICAgICAgdGhlbWVfYncoKSArIGdlb21fYmVlc3dhcm0oZ3JvdXBPblg9RkFMU0UsIGFscGhhID0gMC41KSArIGxhYnMoeSA9ICIiLCB4ID0gIkZlcnJpdGluICjCtWcvbCkiLCBzdWJ0aXRsZSA9IHBhc3RlMCgibWlzc2luZyBkYXRhIGZvciAiLCBmZXJyaXRpbl9taXNzaW5nLCAiIGNhc2VzIikpICsgbGltcyh4ID0gYygwLDExMDAwKSkgKwogICAgICBnZW9tX3ZsaW5lKHhpbnRlcmNlcHQgPSBjb19mZXJyaXRpbiwgbGluZXR5cGUgPSAiZGFzaGVkIiwgY29sb3IgPSAiYmxhY2siKSAKCmZlcnJpdGluX2dyaWQgPC0gcGxvdF9ncmlkKHBfZmVycml0aW5fY29ob3J0LCBwX2ZlcnJpdGluX3NpbmdsZSwgYWxpZ24gPSAidiIsIG5yb3cgPSAyLCByZWxfaGVpZ2h0cyA9IGMoMi8zLCAxLzMpKQpmZXJyaXRpbl9ncmlkCmBgYAoKCiMjIyBUcm9wb25pbgpgYGB7cn0KdHJvcG9uaW5fY29sbGFwc2VfY29ob3J0IDwtIGNvbGxhcHNlX2xhYnZhbHNfY29ob3J0KGRmX2NvaG9ydF9jb250cm9scywgIm1heCIsICJ0cm9wb25pbiIpCnRyb3BvbmluX2NvbGxhcHNlX3NpbmdsZSA8LSBjb2xsYXBzZV9sYWJ2YWxzX3NpbmdsZShkZl9zaW5nbGVjYXNlcywgIm1heCIsICJ0cm9wb25pbiIpCnRyb3BvbmluX21pc3NpbmcgPC0gc3VtKGlzLm5hKHRyb3BvbmluX2NvbGxhcHNlX3NpbmdsZSR0cm9wb25pbl9tYXgpKQoKcF90cm9wb25pbl9jb2hvcnQgPC0gZ2dwbG90KHRyb3BvbmluX2NvbGxhcHNlX2NvaG9ydCwgYWVzKHkgPSBjb2hvcnRfaWQsIHggPSB0cm9wb25pbl9tZWQsIGNvbCA9IGNvaG9ydF90eXBlKSkgKyAKICAgICAgICBnZW9tX3BvaW50KCkgKyAgCiAgICAgICAgZ2VvbV9lcnJvcmJhcihhZXMoeG1pbj10cm9wb25pbl9taW4sIHhtYXg9dHJvcG9uaW5fbWF4KSwgd2lkdGg9LjIsIHBvc2l0aW9uPXBvc2l0aW9uX2RvZGdlKC45KSkgKyBsaW1zKHggPSBjKDAsNzAwMCkpICsgCiAgICAgICAgdGhlbWVfYncoKSArIGxhYnModGl0bGUgPSAiVHJvcG9uaW4iLCB5ID0gImNvaG9ydCIsIHggPSAiIikgICsKICAgICAgICBnZW9tX3ZsaW5lKHhpbnRlcmNlcHQgPSBjb190cm9wbywgbGluZXR5cGUgPSAiZGFzaGVkIiwgY29sb3IgPSAiYmxhY2siKSAgKyB0aGVtZShsZWdlbmQuanVzdGlmaWNhdGlvbiA9IGMoMSwgMSksIGxlZ2VuZC5wb3NpdGlvbiA9IGMoMC45OCwgMC45OCksIGxlZ2VuZC50aXRsZT1lbGVtZW50X2JsYW5rKCkpICsKICAgICAgICBzY2FsZV9jb2xvcl9tYW51YWwodmFsdWVzID0gd2VzX3BhbGV0dGUoIlJveWFsMSIpKQoKcF90cm9wb25pbl9zaW5nbGUgPC0gZ2dwbG90KHRyb3BvbmluX2NvbGxhcHNlX3NpbmdsZSwgYWVzKHggPSBhcy5udW1lcmljKHRyb3BvbmluX21heCksIHkgPSBjb2hvcnRfaWQpKSArCiAgICAgIGdlb21fdmlvbGluKGZpbGwgPSB3ZXNfcGFsZXR0ZSgiRGFyamVlbGluZzIiKVs0XSkgKyAKICAgICAgZ2VvbV9ib3hwbG90KHdpZHRoPS4zLCBmaWxsID0gd2VzX3BhbGV0dGUoIkRhcmplZWxpbmcyIilbMV0pICsgCiAgICAgIHRoZW1lX2J3KCkgKyBnZW9tX2JlZXN3YXJtKGdyb3VwT25YPUZBTFNFLCBhbHBoYSA9IDAuNSkgKyBsYWJzKHkgPSAiIiwgeCA9ICJUcm9wb25pbiAobmcvTCkiLCBzdWJ0aXRsZSA9IHBhc3RlMCgibWlzc2luZyBkYXRhIGZvciAiLCB0cm9wb25pbl9taXNzaW5nLCAiIGNhc2VzIikpICsgbGltcyh4ID0gYygwLDcwMDApKSArCiAgICAgIGdlb21fdmxpbmUoeGludGVyY2VwdCA9IGNvX3Ryb3BvLCBsaW5ldHlwZSA9ICJkYXNoZWQiLCBjb2xvciA9ICJibGFjayIpIAoKdHJvcG9uaW5fZ3JpZCA8LSBwbG90X2dyaWQocF90cm9wb25pbl9jb2hvcnQsIHBfdHJvcG9uaW5fc2luZ2xlLCBhbGlnbiA9ICJ2IiwgbnJvdyA9IDIsIHJlbF9oZWlnaHRzID0gYygyLzMsIDEvMykpCnRyb3BvbmluX2dyaWQKYGBgCgoKIyMjIElMLTYKTm90ZTogVGhlIGNhc2VzIGZyb20gUG91bGV0dHkgZXQgYWwgYXJlIGFkZGVkIHRvIHRoZSBzaW5nbGUgY2FzZXMgYXMgdGhleSByZXBvcnQgb24gSUw2IHZhbHVlcy4gCgpgYGB7cn0KSUw2X2NvbGxhcHNlX2NvaG9ydCA8LSBjb2xsYXBzZV9sYWJ2YWxzX2NvaG9ydChkZl9jb2hvcnRfY29udHJvbHMsICJtYXgiLCAiSUw2IikKSUw2X2NvbGxhcHNlX3NpbmdsZSA8LSBjb2xsYXBzZV9sYWJ2YWxzX3NpbmdsZShkZl9zaW5nbGVjYXNlc19pbmNsUG91bGV0dHksICJtYXgiLCAiSUw2IikKSUw2X21pc3NpbmcgPC0gc3VtKGlzLm5hKElMNl9jb2xsYXBzZV9zaW5nbGUkSUw2X21heCkpCgpwX0lMNl9jb2hvcnQgPC0gZ2dwbG90KElMNl9jb2xsYXBzZV9jb2hvcnQsIGFlcyh5ID0gY29ob3J0X2lkLCB4ID0gSUw2X21lZCkpICsgCiAgICAgICAgZ2VvbV9wb2ludCgpICsgIAogICAgICAgIGdlb21fZXJyb3JiYXIoYWVzKHhtaW49SUw2X21pbiwgeG1heD1JTDZfbWF4KSwgd2lkdGg9LjIsIHBvc2l0aW9uPXBvc2l0aW9uX2RvZGdlKC45KSkgKyBsaW1zKHggPSBjKDAsMjUwMCkpICsgCiAgICAgICAgdGhlbWVfYncoKSArIGxhYnModGl0bGUgPSAiSUw2IiwgeSA9ICJjb2hvcnQiLCB4ID0gIiIpICArCiAgICAgICAgZ2VvbV92bGluZSh4aW50ZXJjZXB0ID0gY29fSUw2LCBsaW5ldHlwZSA9ICJkYXNoZWQiLCBjb2xvciA9ICJibGFjayIpICArCiAgICAgICAgc2NhbGVfY29sb3JfbWFudWFsKHZhbHVlcyA9IHdlc19wYWxldHRlKCJSb3lhbDEiKSkKCnBfSUw2X3NpbmdsZSA8LSBnZ3Bsb3QoSUw2X2NvbGxhcHNlX3NpbmdsZSwgYWVzKHggPSBhcy5udW1lcmljKElMNl9tYXgpLCB5ID0gY29ob3J0X2lkKSkgKwogICAgICBnZW9tX3Zpb2xpbihmaWxsID0gd2VzX3BhbGV0dGUoIkRhcmplZWxpbmcyIilbNF0pICsgCiAgICAgIGdlb21fYm94cGxvdCh3aWR0aD0uMywgZmlsbCA9IHdlc19wYWxldHRlKCJEYXJqZWVsaW5nMiIpWzFdKSArIAogICAgICB0aGVtZV9idygpICsgZ2VvbV9iZWVzd2FybShncm91cE9uWD1GQUxTRSwgYWxwaGEgPSAwLjUpICsgbGFicyh5ID0gIiIsIHggPSAiSUw2IChwZy9tbCkiLCBzdWJ0aXRsZSA9IHBhc3RlMCgibWlzc2luZyBkYXRhIGZvciAiLCBJTDZfbWlzc2luZywgIiBjYXNlcyIpKSArIGxpbXMoeCA9IGMoMCwyNTAwKSkgKwogICAgICBnZW9tX3ZsaW5lKHhpbnRlcmNlcHQgPSBjb19JTDYsIGxpbmV0eXBlID0gImRhc2hlZCIsIGNvbG9yID0gImJsYWNrIikgCgpJTDZfZ3JpZCA8LSBwbG90X2dyaWQocF9JTDZfY29ob3J0LCBwX0lMNl9zaW5nbGUsIGFsaWduID0gInYiLCBucm93ID0gMiwgcmVsX2hlaWdodHMgPSBjKDIvMywgMS8zKSkKSUw2X2dyaWQKYGBgCgoKIyMjIEJOUAoKYGBge3J9CmNvbGxhcHNlX2NvaG9ydCA8LSBjb2xsYXBzZV9sYWJ2YWxzX2NvaG9ydChkZl9jb2hvcnRfY29udHJvbHMsICJtYXgiLCAiX0JOUCIpCmNvbGxhcHNlX3NpbmdsZSA8LSBjb2xsYXBzZV9sYWJ2YWxzX3NpbmdsZShkZl9zaW5nbGVjYXNlcywgIm1heCIsICJfQk5QIikKbWlzc2luZyA8LSBzdW0oaXMubmEoY29sbGFwc2Vfc2luZ2xlJGBfQk5QX21heGApKQoKcF9CTlBfY29ob3J0IDwtIGdncGxvdChjb2xsYXBzZV9jb2hvcnQsIGFlcyh5ID0gY29ob3J0X2lkLCB4ID0gYF9CTlBfbWVkYCwgY29sID0gY29ob3J0X3R5cGUpKSArIAogICAgICAgIGdlb21fcG9pbnQoKSArICAKICAgICAgICBnZW9tX2Vycm9yYmFyKGFlcyh4bWluPWBfQk5QX21pbmAsIHhtYXg9YF9CTlBfbWF4YCksIHdpZHRoPS4yLCBwb3NpdGlvbj1wb3NpdGlvbl9kb2RnZSguOSkpICsgbGltcyh4ID0gYygwLDIwMDAwKSkgKyAKICAgICAgICB0aGVtZV9idygpICsgbGFicyh0aXRsZSA9ICJCTlAiLCB5ID0gImNvaG9ydCIsIHggPSAiIikgICsKICAgICAgICBnZW9tX3ZsaW5lKHhpbnRlcmNlcHQgPSBjb19CTlAsIGxpbmV0eXBlID0gImRhc2hlZCIsIGNvbG9yID0gImJsYWNrIikgICt0aGVtZShsZWdlbmQuanVzdGlmaWNhdGlvbiA9IGMoMSwgMSksIGxlZ2VuZC5wb3NpdGlvbiA9IGMoMC45OCwgMC45OCkpICsKICAgICAgICBzY2FsZV9jb2xvcl9tYW51YWwodmFsdWVzID0gd2VzX3BhbGV0dGUoIlJveWFsMSIpKQoKcF9CTlBfc2luZ2xlIDwtIGdncGxvdChjb2xsYXBzZV9zaW5nbGUsIGFlcyh4ID0gYXMubnVtZXJpYyhgX0JOUF9tYXhgKSwgeSA9IGNvaG9ydF9pZCkpICsKICAgICAgZ2VvbV92aW9saW4oZmlsbCA9IHdlc19wYWxldHRlKCJEYXJqZWVsaW5nMiIpWzRdKSArIAogICAgICBnZW9tX2JveHBsb3Qod2lkdGg9LjMsIGZpbGwgPSB3ZXNfcGFsZXR0ZSgiRGFyamVlbGluZzIiKVsxXSkgKyAKICAgICAgdGhlbWVfYncoKSArIGdlb21fYmVlc3dhcm0oZ3JvdXBPblg9RkFMU0UsIGFscGhhID0gMC41KSArIGxhYnMoeSA9ICIiLCB4ID0gIkJOUCAocGcvbWwpIiwgc3VidGl0bGUgPSBwYXN0ZTAoIm1pc3NpbmcgZGF0YSBmb3IgIiwgbWlzc2luZywgIiBjYXNlcyIpKSArIGxpbXMoeCA9IGMoMCwyMDAwMCkpICsKICAgICAgZ2VvbV92bGluZSh4aW50ZXJjZXB0ID0gY29fQk5QLCBsaW5ldHlwZSA9ICJkYXNoZWQiLCBjb2xvciA9ICJibGFjayIpIAoKQk5QX2dyaWQgPC0gcGxvdF9ncmlkKHBfQk5QX2NvaG9ydCwgcF9CTlBfc2luZ2xlLCBhbGlnbiA9ICJ2IiwgbnJvdyA9IDIsIHJlbF9oZWlnaHRzID0gYygyLzMsIDEvMykpCkJOUF9ncmlkCmBgYAoKIyMjIE5UcHJvQk5QCmBgYHtyfQpjb2xsYXBzZV9jb2hvcnQgPC0gY29sbGFwc2VfbGFidmFsc19jb2hvcnQoZGZfY29ob3J0X2NvbnRyb2xzLCAibWF4IiwgIk5UcHJvQk5QIikKY29sbGFwc2Vfc2luZ2xlIDwtIGNvbGxhcHNlX2xhYnZhbHNfc2luZ2xlKGRmX3NpbmdsZWNhc2VzLCAibWF4IiwgIk5UcHJvQk5QIikKbWlzc2luZyA8LSBzdW0oaXMubmEoY29sbGFwc2Vfc2luZ2xlJE5UcHJvQk5QX21heCkpCgpwX05UcHJvQk5QX2NvaG9ydCA8LSBnZ3Bsb3QoY29sbGFwc2VfY29ob3J0LCBhZXMoeSA9IGNvaG9ydF9pZCwgeCA9IE5UcHJvQk5QX21lZCwgY29sID0gY29ob3J0X3R5cGUpKSArIAogICAgICAgIGdlb21fcG9pbnQoKSArICAKICAgICAgICBnZW9tX2Vycm9yYmFyKGFlcyh4bWluPU5UcHJvQk5QX21pbiwgeG1heD1OVHByb0JOUF9tYXgpLCB3aWR0aD0uMiwgcG9zaXRpb249cG9zaXRpb25fZG9kZ2UoLjkpKSArIGxpbXMoeCA9IGMoMCw3MDAwMCkpICsgCiAgICAgICAgdGhlbWVfYncoKSArIGxhYnModGl0bGUgPSAiTlRwcm9CTlAiLCB5ID0gImNvaG9ydCIsIHggPSAiIikgICsKICAgICAgICBnZW9tX3ZsaW5lKHhpbnRlcmNlcHQgPSBjb19OVHByb0JOUCwgbGluZXR5cGUgPSAiZGFzaGVkIiwgY29sb3IgPSAiYmxhY2siKSArIHRoZW1lKGxlZ2VuZC5qdXN0aWZpY2F0aW9uID0gYygxLCAxKSwgbGVnZW5kLnBvc2l0aW9uID0gYygwLjk4LCAwLjk4KSwgbGVnZW5kLnRpdGxlPWVsZW1lbnRfYmxhbmsoKSkgKwogICAgICAgIHNjYWxlX2NvbG9yX21hbnVhbCh2YWx1ZXMgPSB3ZXNfcGFsZXR0ZSgiUm95YWwxIikpCgpwX05UcHJvQk5QX3NpbmdsZSA8LSBnZ3Bsb3QoY29sbGFwc2Vfc2luZ2xlLCBhZXMoeCA9IGFzLm51bWVyaWMoTlRwcm9CTlBfbWF4KSwgeSA9IGNvaG9ydF9pZCkpICsKICAgICAgZ2VvbV92aW9saW4oZmlsbCA9IHdlc19wYWxldHRlKCJEYXJqZWVsaW5nMiIpWzRdKSArIAogICAgICBnZW9tX2JveHBsb3Qod2lkdGg9LjMsIGZpbGwgPSB3ZXNfcGFsZXR0ZSgiRGFyamVlbGluZzIiKVsxXSkgKyAKICAgICAgdGhlbWVfYncoKSArIGdlb21fYmVlc3dhcm0oZ3JvdXBPblg9RkFMU0UsIGFscGhhID0gMC41KSArIGxhYnMoeSA9ICIiLCB4ID0gIk5UcHJvQk5QIChwZy9tbCkiLCBzdWJ0aXRsZSA9IHBhc3RlMCgibWlzc2luZyBkYXRhIGZvciAiLCBtaXNzaW5nLCAiIGNhc2VzIikpICsgbGltcyh4ID0gYygwLDcwMDAwKSkgKwogICAgICBnZW9tX3ZsaW5lKHhpbnRlcmNlcHQgPSBjb19OVHByb0JOUCwgbGluZXR5cGUgPSAiZGFzaGVkIiwgY29sb3IgPSAiYmxhY2siKSAKCk5UcHJvQk5QX2dyaWQgPC0gcGxvdF9ncmlkKHBfTlRwcm9CTlBfY29ob3J0LCBwX05UcHJvQk5QX3NpbmdsZSwgYWxpZ24gPSAidiIsIG5yb3cgPSAyLCByZWxfaGVpZ2h0cyA9IGMoMi8zLCAxLzMpKQpOVHByb0JOUF9ncmlkCmBgYAoKCiMjIyBQbGF0ZWxldHMKCmBgYHtyfQpjb2xsYXBzZV9jb2hvcnQgPC0gY29sbGFwc2VfbGFidmFsc19jb2hvcnQoZGZfY29ob3J0X2NvbnRyb2xzLCAibWluIiwgInBsYXRlbGV0IikKY29sbGFwc2Vfc2luZ2xlIDwtIGNvbGxhcHNlX2xhYnZhbHNfc2luZ2xlKGRmX3NpbmdsZWNhc2VzLCAibWluIiwgInBsYXRlbGV0IikKbWlzc2luZyA8LSBzdW0oaXMubmEoY29sbGFwc2Vfc2luZ2xlJHBsYXRlbGV0X21pbikpCgpwX3BsYXRlbGV0X2NvaG9ydCA8LSBnZ3Bsb3QoY29sbGFwc2VfY29ob3J0LCBhZXMoeSA9IGNvaG9ydF9pZCwgeCA9IHBsYXRlbGV0X21lZCwgY29sID0gY29ob3J0X3R5cGUpKSArIAogICAgICAgIGdlb21fcG9pbnQoKSArICAKICAgICAgICBnZW9tX2Vycm9yYmFyKGFlcyh4bWluPXBsYXRlbGV0X21pbiwgeG1heD1wbGF0ZWxldF9tYXgsIGNvbD1jb2hvcnRfdHlwZSksIHdpZHRoPS4yLCBwb3NpdGlvbj1wb3NpdGlvbl9kb2RnZSguOSkpICsgbGltcyh4ID0gYygwLDc1MDAwMCkpICsgCiAgICAgICAgdGhlbWVfYncoKSArIGxhYnModGl0bGUgPSAicGxhdGVsZXQiLCB5ID0gImNvaG9ydCIsIHggPSAiIikgICsKICAgICAgICBnZW9tX3ZsaW5lKHhpbnRlcmNlcHQgPSBjb19wbGF0ZWxldCwgbGluZXR5cGUgPSAiZGFzaGVkIiwgY29sb3IgPSAiYmxhY2siKSAgKyB0aGVtZShsZWdlbmQuanVzdGlmaWNhdGlvbiA9IGMoMSwgMSksIGxlZ2VuZC5wb3NpdGlvbiA9IGMoMC45OCwgMC45OCksIGxlZ2VuZC50aXRsZT1lbGVtZW50X2JsYW5rKCkpICsKICAgICAgICBzY2FsZV9jb2xvcl9tYW51YWwodmFsdWVzID0gd2VzX3BhbGV0dGUoIlJveWFsMSIpKQoKcF9wbGF0ZWxldF9zaW5nbGUgPC0gZ2dwbG90KGNvbGxhcHNlX3NpbmdsZSwgYWVzKHggPSBhcy5udW1lcmljKHBsYXRlbGV0X21pbiksIHkgPSBjb2hvcnRfaWQpKSArCiAgICAgIGdlb21fdmlvbGluKGZpbGwgPSB3ZXNfcGFsZXR0ZSgiRGFyamVlbGluZzIiKVs0XSkgKyAKICAgICAgZ2VvbV9ib3hwbG90KHdpZHRoPS4zLCBmaWxsID0gd2VzX3BhbGV0dGUoIkRhcmplZWxpbmcyIilbMV0pICsgCiAgICAgIHRoZW1lX2J3KCkgKyBnZW9tX2JlZXN3YXJtKGdyb3VwT25YPUZBTFNFLCBhbHBoYSA9IDAuNSkgKyBsYWJzKHkgPSAiIiwgeCA9ICJQbGF0ZWxldHMgKC/CtUwpIiwgc3VidGl0bGUgPSBwYXN0ZTAoIm1pc3NpbmcgZGF0YSBmb3IgIiwgbWlzc2luZywgIiBjYXNlcyIpKSArIGxpbXMoeCA9IGMoMCw3NTAwMDApKSArCiAgICAgIGdlb21fdmxpbmUoeGludGVyY2VwdCA9IGNvX3BsYXRlbGV0LCBsaW5ldHlwZSA9ICJkYXNoZWQiLCBjb2xvciA9ICJibGFjayIpIAoKcGxhdGVsZXRfZ3JpZCA8LSBwbG90X2dyaWQocF9wbGF0ZWxldF9jb2hvcnQsIHBfcGxhdGVsZXRfc2luZ2xlLCBhbGlnbiA9ICJ2IiwgbnJvdyA9IDIsIHJlbF9oZWlnaHRzID0gYygyLzMsIDEvMykpCnBsYXRlbGV0X2dyaWQKYGBgCgoKIyMjIEQtZGltZXJzCgpgYGB7cn0KY29sbGFwc2VfY29ob3J0IDwtIGNvbGxhcHNlX2xhYnZhbHNfY29ob3J0KGRmX2NvaG9ydF9jb250cm9scywgIm1heCIsICJEZGltIikKY29sbGFwc2Vfc2luZ2xlIDwtIGNvbGxhcHNlX2xhYnZhbHNfc2luZ2xlKGRmX3NpbmdsZWNhc2VzLCAibWF4IiwgIkRkaW0iKQptaXNzaW5nIDwtIHN1bShpcy5uYShjb2xsYXBzZV9zaW5nbGUkRGRpbV9tYXgpKQoKcF9EZGltX2NvaG9ydCA8LSBnZ3Bsb3QoY29sbGFwc2VfY29ob3J0LCBhZXMoeSA9IGNvaG9ydF9pZCwgeCA9IERkaW1fbWVkLCBjb2wgPSBjb2hvcnRfdHlwZSkpICsgCiAgICAgICAgZ2VvbV9wb2ludCgpICsgIAogICAgICAgIGdlb21fZXJyb3JiYXIoYWVzKHhtaW49RGRpbV9taW4sIHhtYXg9RGRpbV9tYXgsIGNvbD1jb2hvcnRfdHlwZSksIHdpZHRoPS4yLCBwb3NpdGlvbj1wb3NpdGlvbl9kb2RnZSguOSkpICsgbGltcyh4ID0gYygwLDExMDAwKSkgKyAKICAgICAgICB0aGVtZV9idygpICsgbGFicyh0aXRsZSA9ICJELWRpbWVycyIsIHkgPSAiY29ob3J0IiwgeCA9ICIiKSAgKwogICAgICAgIGdlb21fdmxpbmUoeGludGVyY2VwdCA9IGNvX0RkaW0sIGxpbmV0eXBlID0gImRhc2hlZCIsIGNvbG9yID0gImJsYWNrIikgICsgdGhlbWUobGVnZW5kLmp1c3RpZmljYXRpb24gPSBjKDEsIDEpLCBsZWdlbmQucG9zaXRpb24gPSBjKDAuOTgsIDAuOTgpLCBsZWdlbmQudGl0bGU9ZWxlbWVudF9ibGFuaygpKSArCiAgICAgICAgc2NhbGVfY29sb3JfbWFudWFsKHZhbHVlcyA9IHdlc19wYWxldHRlKCJSb3lhbDEiKSkKCnBfRGRpbV9zaW5nbGUgPC0gZ2dwbG90KGNvbGxhcHNlX3NpbmdsZSwgYWVzKHggPSBhcy5udW1lcmljKERkaW1fbWF4KSwgeSA9IGNvaG9ydF9pZCkpICsKICAgICAgZ2VvbV92aW9saW4oZmlsbCA9IHdlc19wYWxldHRlKCJEYXJqZWVsaW5nMiIpWzRdKSArIAogICAgICBnZW9tX2JveHBsb3Qod2lkdGg9LjMsIGZpbGwgPSB3ZXNfcGFsZXR0ZSgiRGFyamVlbGluZzIiKVsxXSkgKyAKICAgICAgdGhlbWVfYncoKSArIGdlb21fYmVlc3dhcm0oZ3JvdXBPblg9RkFMU0UsIGFscGhhID0gMC41KSArIGxhYnMoeSA9ICIiLCB4ID0gIkQtZGltZXJzIChuZy9tbCkiLCBzdWJ0aXRsZSA9IHBhc3RlMCgibWlzc2luZyBkYXRhIGZvciAiLCBtaXNzaW5nLCAiIGNhc2VzIikpICsgbGltcyh4ID0gYygwLDExMDAwKSkgKwogICAgICBnZW9tX3ZsaW5lKHhpbnRlcmNlcHQgPSBjb19EZGltLCBsaW5ldHlwZSA9ICJkYXNoZWQiLCBjb2xvciA9ICJibGFjayIpIAoKRGRpbV9ncmlkIDwtIHBsb3RfZ3JpZChwX0RkaW1fY29ob3J0LCBwX0RkaW1fc2luZ2xlLCBhbGlnbiA9ICJ2IiwgbnJvdyA9IDIsIHJlbF9oZWlnaHRzID0gYygyLzMsIDEvMykpCkRkaW1fZ3JpZApgYGAKCgojIyMgU29kaXVtCgpgYGB7cn0KY29sbGFwc2VfY29ob3J0IDwtIGNvbGxhcHNlX2xhYnZhbHNfY29ob3J0KGRmX2NvaG9ydF9jb250cm9scywgIm1pbiIsICJzb2RpdW0iKQpjb2xsYXBzZV9zaW5nbGUgPC0gY29sbGFwc2VfbGFidmFsc19zaW5nbGUoZGZfc2luZ2xlY2FzZXMsICJtaW4iLCAic29kaXVtIikKbWlzc2luZyA8LSBzdW0oaXMubmEoY29sbGFwc2Vfc2luZ2xlJHNvZGl1bV9taW4pKQoKcF9zb2RpdW1fY29ob3J0IDwtIGdncGxvdChjb2xsYXBzZV9jb2hvcnQsIGFlcyh5ID0gY29ob3J0X2lkLCB4ID0gc29kaXVtX21lZCwgY29sID0gY29ob3J0X3R5cGUpKSArIAogICAgICAgIGdlb21fcG9pbnQoKSArICAKICAgICAgICBnZW9tX2Vycm9yYmFyKGFlcyh4bWluPXNvZGl1bV9taW4sIHhtYXg9c29kaXVtX21heCwgY29sPWNvaG9ydF90eXBlKSwgd2lkdGg9LjIsIHBvc2l0aW9uPXBvc2l0aW9uX2RvZGdlKC45KSkgKyBsaW1zKHggPSBjKDEwMCwyMDApKSArIAogICAgICAgIHRoZW1lX2J3KCkgKyBsYWJzKHRpdGxlID0gIlNvZGl1bSIsIHkgPSAiY29ob3J0IiwgeCA9ICIiKSAgKwogICAgICAgIGdlb21fdmxpbmUoeGludGVyY2VwdCA9IGNvX3NvZGl1bSwgbGluZXR5cGUgPSAiZGFzaGVkIiwgY29sb3IgPSAiYmxhY2siKSAgKyB0aGVtZShsZWdlbmQuanVzdGlmaWNhdGlvbiA9IGMoMSwgMSksIGxlZ2VuZC5wb3NpdGlvbiA9IGMoMC45OCwgMC45OCksIGxlZ2VuZC50aXRsZT1lbGVtZW50X2JsYW5rKCkpICsKICAgICAgICBzY2FsZV9jb2xvcl9tYW51YWwodmFsdWVzID0gd2VzX3BhbGV0dGUoIlJveWFsMSIpKQoKcF9zb2RpdW1fc2luZ2xlIDwtIGdncGxvdChjb2xsYXBzZV9zaW5nbGUsIGFlcyh4ID0gYXMubnVtZXJpYyhzb2RpdW1fbWluKSwgeSA9IGNvaG9ydF9pZCkpICsKICAgICAgZ2VvbV92aW9saW4oZmlsbCA9IHdlc19wYWxldHRlKCJEYXJqZWVsaW5nMiIpWzRdKSArIAogICAgICBnZW9tX2JveHBsb3Qod2lkdGg9LjMsIGZpbGwgPSB3ZXNfcGFsZXR0ZSgiRGFyamVlbGluZzIiKVsxXSkgKyAKICAgICAgdGhlbWVfYncoKSArIGdlb21fYmVlc3dhcm0oZ3JvdXBPblg9RkFMU0UsIGFscGhhID0gMC41KSArIGxhYnMoeSA9ICIiLCB4ID0gIlNvZGl1bSAobW1vbC9MKSIsIHN1YnRpdGxlID0gcGFzdGUwKCJtaXNzaW5nIGRhdGEgZm9yICIsIG1pc3NpbmcsICIgY2FzZXMiKSkgKyBsaW1zKHggPSBjKDEwMCwyMDApKSArCiAgICAgIGdlb21fdmxpbmUoeGludGVyY2VwdCA9IGNvX3NvZGl1bSwgbGluZXR5cGUgPSAiZGFzaGVkIiwgY29sb3IgPSAiYmxhY2siKSAKCnNvZGl1bV9ncmlkIDwtIHBsb3RfZ3JpZChwX3NvZGl1bV9jb2hvcnQsIHBfc29kaXVtX3NpbmdsZSwgYWxpZ24gPSAidiIsIG5yb3cgPSAyLCByZWxfaGVpZ2h0cyA9IGMoMi8zLCAxLzMpKQpzb2RpdW1fZ3JpZApgYGAKCgojIyBDcml0aWNhbCBjYXJlIGludGVydmVudGlvbnMKCiMjIyBJbm90cm9wZXMKYGBge3J9Cm1ha2VCYXJwbG90KHZhcl9pZF9jb2hvcnQgPSAiY3JpdGNhcmVfaW5vdHJvcF9uIiwgdmFyX2lkX3NpbmdsZSA9ICJjcml0Y2FyZV9pbm90cm9wIiwgdmFyX2lkID0gImlub3Ryb3BlcyIpCmBgYAoKYGBge3J9Cm1ha2VIZWF0bWFwX2NvaG9ydCgiY3JpdGNhcmUiLCAiY3JpdGNhcmUiLGV4Y2x1ZGVfc2luZ2xlID0gImRheXMiLCBwbG90dGl0bGUgPSAiQ2FzZXMgcmVjZWl2aW5nIGNyaXRpY2FsIGNhcmUgaW50ZXJ2ZW50aW9ucywgcGVyIGNvaG9ydCIpCgpiYXJTeW1wKCJjcml0Y2FyZSIsICJjcml0Y2FyZSIsIGV4Y2x1ZGVfc2luZ2xlID0gImRheXMiLCBwbG90dGl0bGUgPSAiQ2FzZXMgcmVjZWl2aW5nIGNyaXRpY2FsIGNhcmUgaW50ZXJ2ZW50aW9ucyIpCmBgYAoKIyMgVHJlYXRtZW50cwojIyMgSVZJZwpgYGB7cn0KbWFrZUJhcnBsb3QodmFyX2lkX2NvaG9ydCA9ICJyeF9JVklnX29uY2VfbiIsIHZhcl9pZF9zaW5nbGUgPSAicnhfSVZJZ19vbmNlIiwgdmFyX2lkID0gIklWSWciKQpgYGAKCiMjIyBPdmVyYWxsIHRoZXJhcHkKYGBge3J9Cm1ha2VIZWF0bWFwX2NvaG9ydCgicngiLCAicngiLGV4Y2x1ZGVfc2luZ2xlID0gImRheXMiLCBwbG90dGl0bGUgPSAiQ2FzZXMgcmVjZWl2aW5nIHRyZWF0bWVudCwgcGVyIGNvaG9ydCIpCgoKYmFyU3ltcCgicngiLCAicngiLCBleGNsdWRlX3NpbmdsZSA9ICJkYXlzIiwgcGxvdHRpdGxlID0gIkNhc2VzIHJlY2VpdmluZyB0cmVhdG1lbnQiKQpgYGAKCgojIENhc2UgZGVmaW5pdGlvbnMgCiMjIExhYiByZWZlcmVuY2UgdmFsdWVzCkN1dC1vZmZzIGluIHRoaXMgc3R1ZHk6CgotIE5ldXRyb3BoaWxpYSA+IDgwMDAvwrVMCi0gRWxldmF0ZWQgQ1JQID4gMTAgbWcvTAotIEx5bXBob3BlbmlhIDwgMTI1MC/CtUwKLSBXQkMgPiAxMTAwMC/CtUwKLSBGaWJyaW5vZ2VuID4gNDAwIG1nL2RMCi0gRC1kaW1lcnMgPiAyNTAgbmcvbUwKLSBGZXJyaXRpbiA+IDMwMCBuZy9tTAotIEFsYnVtaW4gPCAzNCBnL0wKLSBQcm9jYWxjaXRvbmluID4gMC40OSBuZy9tTAotIExESCA+IDI4MCBVL0wKLSBJTDYgPiAxNi40IHBnL21MCi0gRVNSID4gMjIgbW0vCi0gQk5QID4gMTAwIHBnL21MCi0gTlRwcm9CTlAgPiA0MDAgcGcvbUwKLSBUcm9wb25pbiA+IDAuMDQgbmcvbUwKCiMjIFJDUENILCBDREMgYW5kIFdITyB7LnRhYnNldH0KCiMjIyBQSU1TLVRTCltTb3VyY2UgUkNQQ0hdKGh0dHBzOi8vd3d3LnJjcGNoLmFjLnVrL3NpdGVzL2RlZmF1bHQvZmlsZXMvMjAyMC0wNS9DT1ZJRC0xOS1QYWVkaWF0cmljLW11bHRpc3lzdGVtLSUyMGluZmxhbW1hdG9yeSUyMHN5bmRyb21lLTIwMjAwNTAxLnBkZikgIAoKMS4gQSBjaGlsZCBwcmVzZW50aW5nIHdpdGggcGVyc2lzdGVudCBmZXZlciwgaW5mbGFtbWF0aW9uIChuZXV0cm9waGlsaWEsIGVsZXZhdGVkIENSUCBhbmQgbHltcGhvcGFlbmlhKSBhbmQgZXZpZGVuY2Ugb2Ygc2luZ2xlIG9yIG11bHRpLW9yZ2FuIGR5c2Z1bmN0aW9uIChzaG9jaywgY2FyZGlhYywgcmVzcGlyYXRvcnksIHJlbmFsLCBnYXN0cm9pbnRlc3RpbmFsIG9yIG5ldXJvbG9naWNhbCBkaXNvcmRlcikgd2l0aCBhZGRpdGlvbmFsIGZlYXR1cmVzIChzZWUgbGlzdGVkIGluIEFwcGVuZGl4IDEgKS4gVGhpcyBtYXkgaW5jbHVkZSBjaGlsZHJlbiBmdWxmaWxsaW5nIGZ1bGwgb3IgcGFydGlhbCBjcml0ZXJpYSBmb3IgS2F3YXNha2kgZGlzZWFzZS4KMi4gRXhjbHVzaW9uIG9mIGFueSBvdGhlciBtaWNyb2JpYWwgY2F1c2UsIGluY2x1ZGluZyBiYWN0ZXJpYWwgc2Vwc2lzLCBzdGFwaHlsb2NvY2NhbCBvciBzdHJlcHRvY29jY2FsIHNob2NrIHN5bmRyb21lcywgaW5mZWN0aW9ucyBhc3NvY2lhdGVkIHdpdGggbXlvY2FyZGl0aXMgc3VjaCBhcyBlbnRlcm92aXJ1cyAod2FpdGluZyBmb3IgcmVzdWx0cyBvZiB0aGVzZSBpbnZlc3RpZ2F0aW9ucyBzaG91bGQgbm90IGRlbGF5IHNlZWtpbmcgZXhwZXJ0IGFkdmljZSkuCjMuIFNBUlMtQ29WLTIgUENSIHRlc3RpbmcgbWF5IGJlIHBvc2l0aXZlIG9yIG5lZ2F0aXZlIAoKV2UgYXJlIHVuYWJsZSB0byBldmFsdWF0ZSBjcml0ZXJpYSAyLgoKYGBge3IsIGZpZy5oZWlnaHQ9IDEwLCBmaWcud2lkdGg9IDh9ClBJTVNfVFNfZnVsZmlsbGVkIDwtIGFwcGx5KGRmX3NpbmdsZWNhc2VzLCAxLCBmdW5jdGlvbihyb3cpIHsKICAgICMgcGVyc2lzdGVudCBmZXZlciwgaW5mbGFtbWF0aW9uIChuZXV0cm9waGlsaWEsIGVsZXZhdGVkIENSUCBhbmQgbHltcGhvcGFlbmlhKSAKICAgIHBhdF9pZCA8LSByb3dbInBhdGllbnRJRF9pbnQiXQogICAgZmV2ZXIgPC0gcm93WyJzeW1wX2ZldmVyIl0gPT0gVFJVRQogICAgbmV1dHJvcGhpbGlhIDwtIGFzLm51bWVyaWMocm93WyJsYWJfbmV1dHJvcGhpbHMiXSkgPiBjb19uZXV0cm9waGlsaWEKICAgIGVsZXZhdGVkX0NSUCA8LSAoYXMubnVtZXJpYyhyb3dbImxhYl9DUlBfYWRtaXMiXSkgPiBjb19DUlAgfCBhcy5udW1lcmljKHJvd1sibGFiX0NSUF9OUyJdKSA+IGNvX0NSUCB8IGFzLm51bWVyaWMocm93WyJsYWJfQ1JQX3BlYWsiXSkgPiBjb19DUlAgKQogICAgbHltcGhvcGVuaWEgPC0gYXMubnVtZXJpYyhyb3dbImxhYl9seW1waG9jeXRlc19sb3dlc3QiXSkgPCBjb19seW1waG8KICAgIGluZmxhbW0gPC0gYW55KGZldmVyLCBuZXV0cm9waGlsaWEsIGVsZXZhdGVkX0NSUCwgbHltcGhvcGVuaWEpCiAgICAKICAgICMgbGFiIHZhbHVlcwogICAgI2ZpYnJpbm9nZW4gPC0gcm93WyJsYWJfZmlicmlubyJdID4gY29fZmlicmlubwogICAgI0RkaW1lcnMgPC0gcm93WyJsYWJfRGRpbV9wZWFrIl0gPiBjb19EZGltIHwgIHJvd1sibGFiX0RkaW1fTlMiXSA+IGNvX0RkaW0KICAgICNmZXJyaXRpbiA8LSAocm93WyJsYWJfZmVycml0aW5fTlMiXSA+IGNvX2ZlcnJpdGluIHwgcm93WyJsYWJfZmVycml0aW5fYWRtaXMiXSA+IGNvX2ZlcnJpdGluIHwgcm93WyJsYWJfZmVycml0aW5fcGVhayJdID4gY29fZmVycml0aW4pCiAgICAjYWxidW1pbiA8LSByb3dbImxhYl9hbGJ1bWluX2FkbWlzIl0gPCBjb19hbGJ1IHwgcm93WyJsYWJfYWxidW1pbl9sb3dlc3QiXSA8IGNvX2FsYnUgfCByb3dbImxhYl9hbGJ1bWluX05TIl0gPCBjb19hbGJ1CiAgICAjbGFiX3ZhbHMgPC0gYW55KGZpYnJpbm9nZW4sIERkaW1lcnMsIGZlcnJpdGluLCBhbGJ1bWluKQogICAgCiAgICAjIHNpbmdsZSBvciBtdWx0aS1vcmdhbiBkeXNmdW5jdGlvbiAoc2hvY2ssIGNhcmRpYWMsIHJlc3BpcmF0b3J5LCByZW5hbCwgZ2FzdHJvaW50ZXN0aW5hbCBvciBuZXVyb2xvZ2ljYWwgZGlzb3JkZXIpCiAgICBwbmV1bW9uaWEgPC0gcm93WyJzeW1wX3Jlc3BfcG5ldW1vbmlhIl0gPT0gVFJVRQogICAgcmVzcF9mYWlsdXJlIDwtIHJvd1sic3ltcF9yZXNwX2ZhaWx1cmUiXSA9PSBUUlVFCiAgICByZXNwIDwtIGFueShwbmV1bW9uaWEsIHJlc3BfZmFpbHVyZSkKICAgIAogICAgQUtJIDwtIHJvd1sic3ltcF9yZW5hbF9BS0kiXSA9PSBUUlVFCiAgICBSUlQgPC0gcm93WyJjcml0Y2FyZV9SUlQiXSA9PSBUUlVFCiAgICByZW5hbCA8LSBhbnkoQUtJLCBSUlQpCiAgICAKICAgIG15b2NhcmRpdGlzIDwtIHJvd1sic3ltcF9jYXJkaW92YXNjX215b2NhcmQiXSA9PSBUUlVFCiAgICBwZXJpY2FyZGl0aXMgPC0gcm93WyJzeW1wX2NhcmRpb3Zhc2NfcGVyaWNhcmQiXSA9PSBUUlVFCiAgICBMVkVGX3VuZGVyMzAgPC0gcm93WyJzeW1wX2NhcmRpb3Zhc2NfTFZfbGVzczMwIl0gPT0gVFJVRQogICAgTFZFRl8zMHRvNTUgPC0gcm93WyJzeW1wX2NhcmRpb3Zhc2NfTFZfMzB0bzU1Il0gPT0gVFJVRQogICAgQk5QIDwtIChhcy5udW1lcmljKHJvd1sibGFiX0JOUF9hZG1pcyJdKSA+IGNvX0JOUCB8IGFzLm51bWVyaWMocm93WyJsYWJfQk5QX21heCJdKSA+IGNvX0JOUCApIAogICAgTlRwcm9CTlAgPC0gYXMubnVtZXJpYyhyb3dbImxhYl9OVHByb0JOUCJdKSA+IGNvX05UcHJvQk5QCiAgICB0cm9wbyA8LSBhcy5udW1lcmljKHJvd1sibGFiX3Ryb3BvbmluX2FkbWlzIl0pID4gY29fdHJvcG8KICAgIHNob2NrIDwtIHJvd1sic3ltcF9jYXJkaW92YXNjX3Nob2NrIl0gPT0gVFJVRQogICAgCiAgICBjYXJkaW92YXNjIDwtIGFueShteW9jYXJkaXRpcywgTFZFRl91bmRlcjMwLCBMVkVGXzMwdG81NSwgTlRwcm9CTlAsIEJOUCwgdHJvcG8sIHNob2NrKQogICAgCiAgICByYXNoIDwtIHJvd1sia2F3YXNha2lfZXhhbnRoZW1hIl0gPT0gVFJVRQogICAgZGVybWF0byA8LSBhbnkocmFzaCkKICAgIAogICAgb3JnYW5fZHlzZnVuYyA8LSBzdW0ocmVzcCwgcmVuYWwsIGNhcmRpb3Zhc2MsIGRlcm1hdG8sIG5hLnJtID0gVFJVRSkgPj0gMQoKICAgIGNyaXRlcmlhX2Z1bGZpbGxlZCA8LSAoaW5mbGFtbSkgJiBvcmdhbl9keXNmdW5jICMmbGFiX3ZhbHMKICAgICNyZXR1cm4oYyhwYXRfaWQsICJjcml0ZXJpYTFfaW5mbGFtbSIgPSBpbmZsYW1tLCAiY3JpdGVyaWEyX2xhYnZhbHMiID0gbGFiX3ZhbHMsICJjcml0ZXJpYTNfb3JnYW5keXNmdW5jIiA9IG9yZ2FuX2R5c2Z1bmMsICJjcml0ZXJpYV9mdWxmaWxsZWQiID0gY3JpdGVyaWFfZnVsZmlsbGVkKSkKICAgIHJldHVybihjKHBhdF9pZCwgImNyaXRlcmlhMV9pbmZsYW1tIiA9IGluZmxhbW0sICJjcml0ZXJpYTJfb3JnYW5keXNmdW5jIiA9IG9yZ2FuX2R5c2Z1bmMsICJjcml0ZXJpYV9mdWxmaWxsZWQiID0gY3JpdGVyaWFfZnVsZmlsbGVkKSkKfSkKClBJTVNfVFNfZnVsZmlsbGVkIDwtIFBJTVNfVFNfZnVsZmlsbGVkICU+JSB0KCkgJT4lIGFzX3RpYmJsZSgpClBJTVNfVFNfZnVsZmlsbGVkIDwtIHR5cGVfY29udmVydChQSU1TX1RTX2Z1bGZpbGxlZCkKUElNU19UU19mdWxmaWxsZWRfaGVhdG1hcCA8LSBQSU1TX1RTX2Z1bGZpbGxlZApjb2xzIDwtIHNhcHBseShQSU1TX1RTX2Z1bGZpbGxlZF9oZWF0bWFwLCBpcy5sb2dpY2FsKQpQSU1TX1RTX2Z1bGZpbGxlZF9oZWF0bWFwWyxjb2xzXSA8LSBsYXBwbHkoUElNU19UU19mdWxmaWxsZWRfaGVhdG1hcFssY29sc10sIGFzLm51bWVyaWMpClBJTVNfVFNfZnVsZmlsbGVkX2hlYXRtYXBfbWVsdCA8LSBQSU1TX1RTX2Z1bGZpbGxlZF9oZWF0bWFwICU+JSBtZWx0KCkKUElNU19UU19mdWxmaWxsZWRfaGVhdG1hcF9tZWx0W2lzLm5hKFBJTVNfVFNfZnVsZmlsbGVkX2hlYXRtYXBfbWVsdCldIDwtIDIKCnNraW0oUElNU19UU19mdWxmaWxsZWQpCgojZ2dwbG90KFBJTVNfVFNfZnVsZmlsbGVkX2hlYXRtYXBfbWVsdCwgYWVzKHggPSB2YXJpYWJsZSwgeSA9IGFzLmNoYXJhY3RlcihwYXRpZW50SURfaW50KSwgZmlsbCA9IGFzLmZhY3Rvcih2YWx1ZSkpKSArIGdlb21fdGlsZSgpICsgdGhlbWVfY2xhc3NpYygpICsgdGhlbWUoYXhpcy5saW5lPWVsZW1lbnRfYmxhbmsoKSkgKyBsYWJzKHkgPSAiUGF0aWVudCBJRCIsIHggPSAiY3JpdGVyaWEiLCBmaWxsID0gImNyaXRlcmlhIG1ldCIsIHRpdGxlID0gIk92ZXJ2aWV3IG9mIHdoaWNoIHNpbmdsZSBjYXNlcyBmdWxmaWxsIFBJTVMtVFMgY2FzZSBkZWZpbml0aW9uIikgKyAgc2NhbGVfZmlsbF9tYW51YWwobGFiZWxzID0gYygiTm8iLCAiWWVzIiwgIk1pc3NpbmciKSwgdmFsdWVzID0gYygicGluazIiLCAicm95YWxibHVlMyIsICJkYXJrZ3JleSIpKSArIHRoZW1lKGF4aXMudGV4dC54PWVsZW1lbnRfdGV4dChhbmdsZT05MCwgaGp1c3Q9MSkpCmBgYAoKIyMjIENEQyBNSVMtQwpbU291cmNlIENEQ10oaHR0cHM6Ly93d3cuY2RjLmdvdi9taXMtYy9oY3AvKSBhbmQgW1VwVG9EYXRlXShodHRwczovL3d3dy51cHRvZGF0ZS5jb20vY29udGVudHMvaW1hZ2U/aW1hZ2VLZXk9UEVEUyUyRjEyODIwMSZ0b3BpY0tleT1QRURTJTJGMTI3NDg4KQpUaGUgY2FzZSBkZWZpbml0aW9uIGZvciBNSVMtQyBpczoKCjEuIEFnZSA8MjEgeWVhcnMKMi4gQ2xpbmljYWwgcHJlc2VudGF0aW9uIGNvbnNpc3RlbnQgd2l0aCBNSVMtQywgaW5jbHVkaW5nIGFsbCBvZiB0aGUgZm9sbG93aW5nOgogICAgLSBGZXZlcgogICAgICAgIC0gRG9jdW1lbnRlZCBmZXZlciA+MzguMMKwQyAoMTAwLjTCsEYpIGZvciDiiaUyNCBob3VycyBvcgogICAgICAgIC0gUmVwb3J0IG9mIHN1YmplY3RpdmUgZmV2ZXIgbGFzdGluZyDiiaUyNCBob3VycwogICAgLSBMYWJvcmF0b3J5IGV2aWRlbmNlIG9mIGluZmxhbW1hdGlvbgogICAgLSBTZXZlcmUgaWxsbmVzcyByZXF1aXJpbmcgaG9zcGl0YWxpemF0aW9uCiAgICAtIE11bHRpc3lzdGVtIGludm9sdmVtZW50CiAgICAgICAgLSAyIG9yIG1vcmUgb3JnYW4gc3lzdGVtcyBpbnZvbHZlZAogICAgICAgICAgICAtIENhcmRpb3Zhc2N1bGFyIChlZywgc2hvY2ssIGVsZXZhdGVkIHRyb3BvbmluLCBlbGV2YXRlZCBCTlAsIGFibm9ybWFsIGVjaG9jYXJkaW9ncmFtLCBhcnJoeXRobWlhKQogICAgICAgICAgICAtIFJlc3BpcmF0b3J5IChlZywgcG5ldW1vbmlhLCBBUkRTLCBwdWxtb25hcnkgZW1ib2xpc20pCiAgICAgICAgICAgIC0gUmVuYWwgKGVnLCBBS0ksIHJlbmFsIGZhaWx1cmUpCiAgICAgICAgICAgIC0gTmV1cm9sb2dpYyAoZWcsIHNlaXp1cmUsIHN0cm9rZSwgYXNlcHRpYyBtZW5pbmdpdGlzKQogICAgICAgICAgICAtIEhlbWF0b2xvZ2ljIChlZywgY29hZ3Vsb3BhdGh5KQogICAgICAgICAgICAtIEdhc3Ryb2ludGVzdGluYWwgKGVnLCBlbGV2YXRlZCBsaXZlciBlbnp5bWVzLCBkaWFycmhlYSwgaWxldXMsIGdhc3Ryb2ludGVzdGluYWwgYmxlZWRpbmcpCiAgICAgICAgICAgIC0gRGVybWF0b2xvZ2ljIChlZywgZXJ5dGhyb2Rlcm1hLCBtdWNvc2l0aXMsIG90aGVyIHJhc2gpCjMuIE5vIGFsdGVybmF0aXZlIHBsYXVzaWJsZSBkaWFnbm9zZXMKNC4gUmVjZW50IG9yIGN1cnJlbnQgU0FSUy1Db1YtMiBpbmZlY3Rpb24gb3IgZXhwb3N1cmUKICAgIC0gQW55IG9mIHRoZSBmb2xsb3dpbmc6CiAgICAtIFBvc2l0aXZlIFNBUlMtQ29WLTIgUlQtUENSCiAgICAtIFBvc2l0aXZlIHNlcm9sb2d5CiAgICAtIFBvc2l0aXZlIGFudGlnZW4gdGVzdAogICAgLSBDT1ZJRC0xOSBleHBvc3VyZSB3aXRoaW4gdGhlIDQgd2Vla3MgcHJpb3IgdG8gdGhlIG9uc2V0IG9mIHN5bXB0b21zCgoKCmBgYHtyLCBmaWcuaGVpZ2h0PSAxMCwgZmlnLndpZHRoPSA4fQoKQ0RDX2Z1bGZpbGxlZCA8LSBhcHBseShkZl9zaW5nbGVjYXNlcywgMSwgZnVuY3Rpb24ocm93KSB7CiAgICAjIGNyaXRlcmlhIDEKICAgIGNyaXRlcmlhMSA9IFRSVUUKICAgIAogICAgIyBjcml0ZXJpYSAyCiAgICBwYXRfaWQgPC0gcm93WyJwYXRpZW50SURfaW50Il0KICAgIAogICAgIyBmZXZlcj8KICAgIGZldmVyIDwtIHJvd1sic3ltcF9mZXZlciJdID09IFRSVUUgfCByb3dbImthd2FzYWtpX2ZldmVyIl0gPT0gVFJVRQoKICAgIGluZmxhbW0gPC0gYW55KGZldmVyKQogICAgCiAgICAjIGxhYiB2YWx1ZXMgZXZpZGVuY2UgZm9yIGluZmxhbW1hdGlvbgogICAgbmV1dHJvcGhpbGlhIDwtIGFzLm51bWVyaWMocm93WyJsYWJfbmV1dHJvcGhpbHMiXSkgPiBjb19uZXV0cm9waGlsaWEKICAgIGVsZXZhdGVkX0NSUCA8LSAoYXMubnVtZXJpYyhyb3dbImxhYl9DUlBfYWRtaXMiXSkgPiBjb19DUlAgfCBhcy5udW1lcmljKHJvd1sibGFiX0NSUF9OUyJdKSA+IGNvX0NSUCB8IGFzLm51bWVyaWMocm93WyJsYWJfQ1JQX3BlYWsiXSkgPiBjb19DUlAgKQogICAgbHltcGhvcGVuaWEgPC0gYXMubnVtZXJpYyhyb3dbImxhYl9seW1waG9jeXRlc19sb3dlc3QiXSkgPCBjb19seW1waG8KICAgIGZpYnJpbm9nZW4gPC0gYXMubnVtZXJpYyhyb3dbImxhYl9maWJyaW5vIl0pID4gY29fZmlicmlubwogICAgRGRpbWVycyA8LSBhcy5udW1lcmljKHJvd1sibGFiX0RkaW1fcGVhayJdKSA+IGNvX0RkaW0gfCAgYXMubnVtZXJpYyhyb3dbImxhYl9EZGltX05TIl0pID4gY29fRGRpbQogICAgZmVycml0aW4gPC0gKGFzLm51bWVyaWMocm93WyJsYWJfZmVycml0aW5fTlMiXSkgPiBjb19mZXJyaXRpbiB8IGFzLm51bWVyaWMocm93WyJsYWJfZmVycml0aW5fYWRtaXMiXSkgPiBjb19mZXJyaXRpbiB8IGFzLm51bWVyaWMocm93WyJsYWJfZmVycml0aW5fcGVhayJdKSA+IGNvX2ZlcnJpdGluKQogICAgYWxidW1pbiA8LSBhcy5udW1lcmljKHJvd1sibGFiX2FsYnVtaW5fYWRtaXMiXSkgPCBjb19hbGJ1IHwgYXMubnVtZXJpYyhyb3dbImxhYl9hbGJ1bWluX2xvd2VzdCJdKSA8IGNvX2FsYnUgfCBhcy5udW1lcmljKHJvd1sibGFiX2FsYnVtaW5fTlMiXSkgPCBjb19hbGJ1CiAgICBQQ1QgPC0gYXMubnVtZXJpYyhyb3dbImxhYl9QQ1RfYWRtaXMiXSkgPiBjb19QQ1QgfCBhcy5udW1lcmljKHJvd1sibGFiX1BDVF9wZWFrIl0pID4gY29fUENUIHwgYXMubnVtZXJpYyhyb3dbImxhYl9QQ1RfTlMiXSkgPiBjb19QQ1QgCiAgICBMREggPC0gYXMubnVtZXJpYyhyb3dbImxhYl9MREgiXSkgPiBjb19MREgKICAgIElMNiA8LSBhcy5udW1lcmljKHJvd1sibGFiX0lMNiJdKSA+IGNvX0lMNgogICAgRVNSIDwtIGFzLm51bWVyaWMocm93WyJsYWJfRVNSIl0pID4gY29fRVNSCgogICAgbGFiX3ZhbHMgPC0gYW55KG5ldXRyb3BoaWxpYSwgZWxldmF0ZWRfQ1JQLCBseW1waG9wZW5pYSwgZmlicmlub2dlbiwgRGRpbWVycywgZmVycml0aW4sIGFsYnVtaW4sIFBDVCwgTERILCBJTDYsIEVTUikKICAgIAogICAgIyBJbG5lc3MgcmVxdWlyaW5nIGhvc3BpdGFsaXNhdGlvbgogICAgIyMgdXNlZCBzdXJyb2dhdGUgcGFyYW1ldGVycyBmb3IgaG9zcAogICAgaG9zcF9JQ1UgPC0gcm93WyJhZG1pc19ob3NwX2RheXMiXSA+IDEgfCByb3dbImFkbWlzX0lDVV9kYXlzIl0gPiAxIHwgcm93WyJhZG1pc19QSUNVX2FkbWlzIl0gPT0gVFJVRQogICAgTklWIDwtIHJvd1siY3JpdGNhcmVfTklWIl0gPT0gVFJVRSB8IHJvd1siY3JpdGNhcmVfTklWX2RheXMiXSA+IDEKICAgIE1WIDwtIHJvd1siY3JpdGNhcmVfTVYiXSA9PSBUUlVFIHwgcm93WyJjcml0Y2FyZV9NVl9kYXlzIl0gPiAxCiAgICBpbm90cm9wIDwtIHJvd1siY3JpdGNhcmVfaW5vdHJvcCJdID09IFRSVUUgfCByb3dbImNyaXRjYXJlX2lub3Ryb3BfZGF5cyJdID4gMQogICAgRUNNTyA8LSByb3dbImNyaXRjYXJlX0VDTU8iXSA9PSBUUlVFIAogICAgSVZJZyA8LSByb3dbInJ4X0lWSWdfb25jZSJdID09IFRSVUUgIHwgIHJvd1sicnhfSVZJZ19tdWx0aXAiXSA9PSBUUlVFIAogICAgYmlvbG9naWNhbHMgPC0gcm93WyJyeF9hbmFraW5yYSJdID09IFRSVUUgfCByb3dbInJ4X3RvY2lsaXp1bWFiIl0gPT0gVFJVRSB8IHJvd1sicnhfaW5mbGl4aW1hYiJdID09IFRSVUUgfCByb3dbInJ4X2FudGliaW90aWNzIl0gPT0gVFJVRSB8IHJvd1sicnhfcGxhc21hIl0gPT0gVFJVRSB8IHJvd1sicnhfcmVtZGVzaXZpciJdID09IFRSVUUgCiAgICBoZXBhcmluIDwtIHJvd1sicnhfaGVwYXJpbiJdID09IFRSVUUKCgogICAgcmVxX2hvc3AgPC0gYW55KGhvc3BfSUNVLCBOSVYsIE1WLCBpbm90cm9wLCBFQ01PLCBJVklnLCBiaW9sb2dpY2FscywgaGVwYXJpbikKICAgIAogICAgIyMgbXVsdGlzeXN0ZW0gaW52b2x2ZW1lbnQgPj0gMgogICAgIyMgcmVzcGlyYXRvcnkKICAgIHBuZXVtb25pYSA8LSByb3dbInN5bXBfcmVzcF9wbmV1bW9uaWEiXSA9PSBUUlVFCiAgICByZXNwX2ZhaWx1cmUgPC0gcm93WyJzeW1wX3Jlc3BfZmFpbHVyZSJdID09IFRSVUUKICAgIHJlc3AgPC0gYW55KHBuZXVtb25pYSwgcmVzcF9mYWlsdXJlKQogICAgCiAgICBBS0kgPC0gcm93WyJzeW1wX3JlbmFsX0FLSSJdID09IFRSVUUKICAgIFJSVCA8LSByb3dbImNyaXRjYXJlX1JSVCJdID09IFRSVUUKICAgIHJlbmFsIDwtIGFueShBS0ksIFJSVCkKICAgIAogICAgbXlvY2FyZGl0aXMgPC0gcm93WyJzeW1wX2NhcmRpb3Zhc2NfbXlvY2FyZCJdID09IFRSVUUKICAgIHBlcmljYXJkaXRpcyA8LSByb3dbInN5bXBfY2FyZGlvdmFzY19wZXJpY2FyZCJdID09IFRSVUUKICAgIExWRUZfdW5kZXIzMCA8LSByb3dbInN5bXBfY2FyZGlvdmFzY19MVl9sZXNzMzAiXSA9PSBUUlVFCiAgICBMVkVGXzMwdG81NSA8LSByb3dbInN5bXBfY2FyZGlvdmFzY19MVl8zMHRvNTUiXSA9PSBUUlVFCiAgICBCTlAgPC0gKGFzLm51bWVyaWMocm93WyJsYWJfQk5QX2FkbWlzIl0pID4gY29fQk5QIHwgYXMubnVtZXJpYyhyb3dbImxhYl9CTlBfbWF4Il0pID4gY29fQk5QICkgCiAgICBOVHByb0JOUCA8LSBhcy5udW1lcmljKHJvd1sibGFiX05UcHJvQk5QIl0pID4gY29fTlRwcm9CTlAKICAgIHRyb3BvIDwtIGFzLm51bWVyaWMocm93WyJsYWJfdHJvcG9uaW5fYWRtaXMiXSkgPiBjb190cm9wbwogICAgc2hvY2sgPC0gcm93WyJzeW1wX2NhcmRpb3Zhc2Nfc2hvY2siXSA9PSBUUlVFCiAgICAKICAgIGNhcmRpb3Zhc2MgPC0gYW55KG15b2NhcmRpdGlzLCBMVkVGX3VuZGVyMzAsIExWRUZfMzB0bzU1LCBOVHByb0JOUCwgQk5QLCB0cm9wbywgc2hvY2spCiAgICAKICAgIHJhc2ggPC0gcm93WyJrYXdhc2FraV9leGFudGhlbWEiXSA9PSBUUlVFCiAgICBkZXJtYXRvIDwtIGFueShyYXNoKQogICAgCiAgICBvcmdhbl9keXNmdW5jIDwtIHN1bShyZXNwLCByZW5hbCwgY2FyZGlvdmFzYywgZGVybWF0bywgbmEucm0gPSBUUlVFKSA+PSAyCiAgICAKICAgIGNyaXRlcmlhMiA8LSBzdW0oaW5mbGFtbSwgbGFiX3ZhbHMsIHJlcV9ob3NwLCBvcmdhbl9keXNmdW5jLCBuYS5ybSA9IFRSVUUpID09IDQKICAgICMgY3JpdGVyaWEgMwogICAgIyMgbm90IGV2YWx1YWJsZQogICAgY3JpdGVyaWEzID0gVFJVRQogICAgIyBjcml0ZXJpYSA0CiAgICAjIENPVklEIHBvcz8KICAgIFBDUl9wb3MgPC0gcm93WyJjb3ZpZF9QQ1JfcG9zIl0gPT0gVFJVRQogICAgc3Rvb2xfcG9zIDwtIHJvd1siY292aWRfUENSX3N0b29sX3BvcyJdID09IFRSVUUKICAgIGNsb3NlY29udGFjdCA8LSByb3dbImNvdmlkX2Nsb3NlY29udGFjdCJdID09IFRSVUUKICAgIElnQSA8LSByb3dbImNvdmlkX0lnQV9wb3MiXSA9PSBUUlVFCiAgICBJZ00gPC0gcm93WyJjb3ZpZF9JZ01fcG9zIl0gPT0gVFJVRSAgICAKICAgIElnRyA8LSByb3dbImNvdmlkX0lnR19wb3MiXSA9PSBUUlVFICAgIAogICAgYW55X3Nlcm8gPC0gcm93WyJjb3ZpZF9zZXJvX3BvcyJdID09IFRSVUUKICAgIAogICAgY3JpdGVyaWE0IDwtIGFueShQQ1JfcG9zLCBzdG9vbF9wb3MsIGNsb3NlY29udGFjdCwgSWdBLCBJZ00sIElnRywgYW55X3Nlcm8pCiAgICAKICAgIGlmIChGQUxTRSAlaW4lIGMoY3JpdGVyaWExLCBjcml0ZXJpYTIsIGNyaXRlcmlhMywgY3JpdGVyaWE0KSl7CiAgICAgIGNyaXRlcmlhX2Z1bGZpbGxlZCA8LSBGQUxTRQogICAgfSBlbHNlIGlmIChOQSAlaW4lIGMoY3JpdGVyaWExLCBjcml0ZXJpYTIsIGNyaXRlcmlhMywgY3JpdGVyaWE0KSl7CiAgICAgIGNyaXRlcmlhX2Z1bGZpbGxlZCA8LSBOQQogICAgfSBlbHNlIGlmIChzdW0oY3JpdGVyaWExLCBjcml0ZXJpYTIsIGNyaXRlcmlhMywgY3JpdGVyaWE0LCBuYS5ybSA9IFRSVUUpID09IDQpewogICAgICBjcml0ZXJpYV9mdWxmaWxsZWQgPC0gVFJVRQogICAgfQogICAgCiAgICAjY3JpdGVyaWFfZnVsZmlsbGVkIDwtIHN1bShjcml0ZXJpYTEsIGNyaXRlcmlhMiwgY3JpdGVyaWEzLCBjcml0ZXJpYTQsIG5hLnJtID0gVFJVRSkgPT0gNAogICAgcmV0dXJuKGMocGF0X2lkLCAiY3JpdGVyaWExX2FnZSIgPSBjcml0ZXJpYTEsICJjcml0ZXJpYTJfY2xpbmljYWwiID0gY3JpdGVyaWEyLCAiY3JpdGVyaWEzX25vQWx0IiA9IGNyaXRlcmlhMywgImNyaXRlcmlhNF9yZWNlbnRFeHBvc3VyZSIgPSBjcml0ZXJpYTQsICJjcml0ZXJpYV9mdWxmaWxsZWQiID0gY3JpdGVyaWFfZnVsZmlsbGVkKSkKfSkKCkNEQ19mdWxmaWxsZWQgPC0gQ0RDX2Z1bGZpbGxlZCAlPiUgdCgpICU+JSBhc190aWJibGUoKQpDRENfZnVsZmlsbGVkIDwtIHR5cGVfY29udmVydChDRENfZnVsZmlsbGVkKQpDRENfZnVsZmlsbGVkX2hlYXRtYXAgPC0gQ0RDX2Z1bGZpbGxlZApjb2xzIDwtIHNhcHBseShDRENfZnVsZmlsbGVkX2hlYXRtYXAsIGlzLmxvZ2ljYWwpCkNEQ19mdWxmaWxsZWRfaGVhdG1hcFssY29sc10gPC0gbGFwcGx5KENEQ19mdWxmaWxsZWRfaGVhdG1hcFssY29sc10sIGFzLm51bWVyaWMpCkNEQ19mdWxmaWxsZWRfaGVhdG1hcF9tZWx0IDwtIENEQ19mdWxmaWxsZWRfaGVhdG1hcCAlPiUgbWVsdCgpCkNEQ19mdWxmaWxsZWRfaGVhdG1hcF9tZWx0W2lzLm5hKENEQ19mdWxmaWxsZWRfaGVhdG1hcF9tZWx0KV0gPC0gMgoKc2tpbShDRENfZnVsZmlsbGVkKQojZ2dwbG90KENEQ19mdWxmaWxsZWRfaGVhdG1hcF9tZWx0LCBhZXMoeCA9IHZhcmlhYmxlLCB5ID0gYXMuY2hhcmFjdGVyKHBhdGllbnRJRF9pbnQpLCBmaWxsID0gYXMuZmFjdG9yKHZhbHVlKSkpICsgZ2VvbV90aWxlKCkgKyB0aGVtZV9jbGFzc2ljKCkgKyB0aGVtZShheGlzLmxpbmU9ZWxlbWVudF9ibGFuaygpKSArIGxhYnMoeSA9ICJQYXRpZW50IElEIiwgeCA9ICJjcml0ZXJpYSIsIGZpbGwgPSAiY3JpdGVyaWEgbWV0IiwgdGl0bGUgPSAiT3ZlcnZpZXcgb2Ygd2hpY2ggc2luZ2xlIGNhc2VzIGZ1bGZpbGwgQ0RDIE1JUy1DIGNhc2UgZGVmaW5pdGlvbiIpICsgIHNjYWxlX2ZpbGxfbWFudWFsKGxhYmVscyA9IGMoIk5vIiwgIlllcyIsICJNaXNzaW5nIiksIHZhbHVlcyA9IGMoInBpbmsyIiwgInJveWFsYmx1ZTMiLCAiZGFya2dyZXkiKSkgKyB0aGVtZShheGlzLnRleHQueD1lbGVtZW50X3RleHQoYW5nbGU9OTAsIGhqdXN0PTEpKQpgYGAKCiMjIyBXSE8gY2FzZSBkZWZpbml0aW9uCltTb3VyY2UgVXBUb0RhdGVdKGh0dHBzOi8vd3d3LnVwdG9kYXRlLmNvbS9jb250ZW50cy9pbWFnZT9pbWFnZUtleT1QRURTJTJGMTI4MjAxJnRvcGljS2V5PVBFRFMlMkYxMjc0ODgpOgoKQWxsIDYgY3JpdGVyaWEgbXVzdCBiZSBtZXQ6CgoxLiBBZ2UgMCB0byAxOSB5ZWFycwoyLiBGZXZlciBmb3Ig4omlMyBkYXlzCjMuIENsaW5pY2FsIHNpZ25zIG9mIG11bHRpc3lzdGVtIGludm9sdmVtZW50IChhdCBsZWFzdCAyIG9mIHRoZSBmb2xsb3dpbmcpOgogICAgLSBSYXNoLCBiaWxhdGVyYWwgbm9ucHVydWxlbnQgY29uanVuY3Rpdml0aXMsIG9yIG11Y29jdXRhbmVvdXMgaW5mbGFtbWF0aW9uIHNpZ25zIChvcmFsLCBoYW5kcywgb3IgZmVldCkKICAgIC0gSHlwb3RlbnNpb24gb3Igc2hvY2sKICAgIC0gQ2FyZGlhYyBkeXNmdW5jdGlvbiwgcGVyaWNhcmRpdGlzLCB2YWx2dWxpdGlzLCBvciBjb3JvbmFyeSBhYm5vcm1hbGl0aWVzIChpbmNsdWRpbmcgZWNob2NhcmRpb2dyYXBoaWMgZmluZGluZ3Mgb3IgZWxldmF0ZWQgdHJvcG9uaW4vQk5QKQogICAgLSBFdmlkZW5jZSBvZiBjb2FndWxvcGF0aHkgKHByb2xvbmdlZCBQVCBvciBQVFQ7IGVsZXZhdGVkIEQtZGltZXIpCiAgICAtIEFjdXRlIGdhc3Ryb2ludGVzdGluYWwgc3ltcHRvbXMgKGRpYXJyaGVhLCB2b21pdGluZywgb3IgYWJkb21pbmFsIHBhaW4pCjQuIEVsZXZhdGVkIG1hcmtlcnMgb2YgaW5mbGFtbWF0aW9uIChlZywgRVNSLCBDUlAsIG9yIHByb2NhbGNpdG9uaW4pCjUuIE5vIG90aGVyIG9idmlvdXMgbWljcm9iaWFsIGNhdXNlIG9mIGluZmxhbW1hdGlvbiwgaW5jbHVkaW5nIGJhY3RlcmlhbCBzZXBzaXMgYW5kIHN0YXBoeWxvY29jY2FsL3N0cmVwdG9jb2NjYWwgdG94aWMgc2hvY2sgc3luZHJvbWVzCjYuIEV2aWRlbmNlIG9mIFNBUlMtQ29WLTIgaW5mZWN0aW9uCiAgICAtIEFueSBvZiB0aGUgZm9sbG93aW5nOgogICAgLSBQb3NpdGl2ZSBTQVJTLUNvVi0yIFJULVBDUgogICAgLSBQb3NpdGl2ZSBzZXJvbG9neQogICAgLSBQb3NpdGl2ZSBhbnRpZ2VuIHRlc3QKICAgIC0gQ29udGFjdCB3aXRoIGFuIGluZGl2aWR1YWwgd2l0aCBDT1ZJRC0xOQoKYGBge3IsIGZpZy5oZWlnaHQ9IDEwLCBmaWcud2lkdGg9IDh9CiNyb3cgPC0gZGZfc2luZ2xlY2FzZXNbODcsIF0KV0hPX2Z1bGZpbGxlZCA8LSBhcHBseShkZl9zaW5nbGVjYXNlcywgMSwgZnVuY3Rpb24ocm93KSB7CiAgICBwYXRfaWQgPC0gcm93WyJwYXRpZW50SURfaW50Il0KICAgIAogICAgIyBjcml0ZXJpYSAxCiAgICBjcml0ZXJpYTEgPSBUUlVFCiAgICAKICAgICMgY3JpdGVyaWEgMjogZmV2ZXI/CiAgICBmZXZlciA8LSByb3dbInN5bXBfZmV2ZXIiXSA9PSBUUlVFIHwgcm93WyJrYXdhc2FraV9mZXZlciJdID09IFRSVUUKCiAgICBjcml0ZXJpYTIgPC0gYW55KGZldmVyKQogICAgCiAgICAjIGNyaXRlcmlhIDM6IGNsaW5pY2FsIHNpZ25zIG9mIG11bHRpc3lzdGVtIGludm9sdmVtZW50IChhdCBsZWFzdCAyKQogICAgIyMgUmFzaCwgYmlsYXRlcmFsIG5vbnB1cnVsZW50IGNvbmp1bmN0aXZpdGlzLCBvciBtdWNvY3V0YW5lb3VzIGluZmxhbW1hdGlvbiBzaWducyAob3JhbCwgaGFuZHMsIG9yIGZlZXQpCiAgICByYXNoIDwtIHJvd1sia2F3YXNha2lfZXhhbnRoZW1hIl0gPT0gVFJVRQogICAgY29uanVuY3Rpdml0aXMgPC0gcm93WyJrYXdhc2FraV9jb25qdW5jdGl2aXRpcyJdID09IFRSVUUKICAgIG11Y29jdXRhbmVhb3VzIDwtIHJvd1sia2F3YXNha2lfbW91dGgiXSA9PSBUUlVFIHwgcm93WyJrYXdhc2FraV9leHRyZW1pdHkiXSA9PSBUUlVFCiAgICAKICAgIGNyaXRlcmlhM19hIDwtIGFueShyYXNoLCBjb25qdW5jdGl2aXRpcywgbXVjb2N1dGFuZWFvdXMpCiAgICAKICAgICMjIGh5cG90ZW5zaW9uIG9yIHNob2NrCiAgICBzaG9jayA8LSByb3dbInN5bXBfY2FyZGlvdmFzY19zaG9jayJdID09IFRSVUUKICAgIGNyaXRlcmlhM19iIDwtIGFueShzaG9jaykKICAgIAogICAgIyMgY2FyZGlhYyBkeXNmdW5jdGlvbgogICAgbXlvY2FyZGl0aXMgPC0gcm93WyJzeW1wX2NhcmRpb3Zhc2NfbXlvY2FyZCJdID09IFRSVUUKICAgIHBlcmljYXJkaXRpcyA8LSByb3dbInN5bXBfY2FyZGlvdmFzY19wZXJpY2FyZCJdID09IFRSVUUKICAgIExWRUZfdW5kZXIzMCA8LSByb3dbInN5bXBfY2FyZGlvdmFzY19MVl9sZXNzMzAiXSA9PSBUUlVFCiAgICBMVkVGXzMwdG81NSA8LSByb3dbInN5bXBfY2FyZGlvdmFzY19MVl8zMHRvNTUiXSA9PSBUUlVFCiAgICBCTlAgPC0gKGFzLm51bWVyaWMocm93WyJsYWJfQk5QX2FkbWlzIl0pID4gY29fQk5QIHwgYXMubnVtZXJpYyhyb3dbImxhYl9CTlBfbWF4Il0pID4gY29fQk5QICkgCiAgICBOVHByb0JOUCA8LSBhcy5udW1lcmljKHJvd1sibGFiX05UcHJvQk5QIl0pID4gY29fTlRwcm9CTlAKICAgIHRyb3BvIDwtIGFzLm51bWVyaWMocm93WyJsYWJfdHJvcG9uaW5fYWRtaXMiXSkgPiBjb190cm9wbwogICAgY29yb25hcnkgPC0gcm93WyJzeW1wX2NhcmRpb3Zhc2NfY29yZGlsYXQiXSA9PSBUUlVFIHwgcm93WyJzeW1wX2NhcmRpb3Zhc2NfYW5ldXJ5c20iXSA9PSBUUlVFCiAgICAKICAgIGNyaXRlcmlhM19jIDwtIGFueShteW9jYXJkaXRpcywgTFZFRl91bmRlcjMwLCBMVkVGXzMwdG81NSwgTlRwcm9CTlAsIEJOUCwgdHJvcG8sIGNvcm9uYXJ5KQogICAgCiAgICAjIyBjb2FndWxvcGF0aHkKICAgIGZpYnJpbm9nZW4gPC0gYXMubnVtZXJpYyhyb3dbImxhYl9maWJyaW5vIl0pID4gY29fZmlicmlubwogICAgRGRpbWVycyA8LSBhcy5udW1lcmljKHJvd1sibGFiX0RkaW1fcGVhayJdKSA+IGNvX0RkaW0gfCAgYXMubnVtZXJpYyhyb3dbImxhYl9EZGltX05TIl0pID4gY29fRGRpbQogICAgCiAgICBjcml0ZXJpYTNfZCA8LSBhbnkoZmlicmlub2dlbiwgRGRpbWVycykKICAgIAogICAgIyMgYWN1dGUgR0kgc3ltcHRvbXMKICAgIEdJc3ltcCA8LSByb3dbInN5bXBfR0lfTlMiXSA9PSBUUlVFIHwgcm93WyJzeW1wX0dJX2FiZG9wYWluIl0gPT0gVFJVRSB8IHJvd1sic3ltcF9HSV92b21pdGluZyJdID09IFRSVUUgfCByb3dbInN5bXBfR0lfZGlhcnJoIl0gPT0gVFJVRSB8IHJvd1sic3ltcF9HSV9jb2xpdGlzIl0gPT0gVFJVRSAKICAgIAogICAgY3JpdGVyaWEzX2UgPC0gYW55KEdJc3ltcCkKICAgIAogICAgY3JpdGVyaWEzIDwtIHN1bShjcml0ZXJpYTNfYSwgY3JpdGVyaWEzX2IsIGNyaXRlcmlhM19jLCBjcml0ZXJpYTNfZCwgY3JpdGVyaWEzX2UsIG5hLnJtID0gVFJVRSkgPj0gMgogICAgICAKICAgICMgY3JpdGVyaWEgNDogRWxldmF0ZWQgbWFya2VycyBvZiBpbmZsYW1tYXRpb24gKGVnLCBFU1IsIENSUCwgb3IgcHJvY2FsY2l0b25pbikKICAgIG5ldXRyb3BoaWxpYSA8LSBhcy5udW1lcmljKHJvd1sibGFiX25ldXRyb3BoaWxzIl0pID4gY29fbmV1dHJvcGhpbGlhCiAgICBlbGV2YXRlZF9DUlAgPC0gKGFzLm51bWVyaWMocm93WyJsYWJfQ1JQX2FkbWlzIl0pID49IGNvX0NSUCkgfCAoYXMubnVtZXJpYyhyb3dbImxhYl9DUlBfTlMiXSkgPj0gY29fQ1JQKSB8IChhcy5udW1lcmljKHJvd1sibGFiX0NSUF9wZWFrIl0pID49IGNvX0NSUCApCiAgIyAgcHJpbnQocGFzdGUwKHBhdF9pZCwgZWxldmF0ZWRfQ1JQLCByb3dbImxhYl9DUlBfcGVhayJdKSkKICAgIGx5bXBob3BlbmlhIDwtIGFzLm51bWVyaWMocm93WyJsYWJfbHltcGhvY3l0ZXNfbG93ZXN0Il0pIDwgY29fbHltcGhvCgogICAgZmVycml0aW4gPC0gKGFzLm51bWVyaWMocm93WyJsYWJfZmVycml0aW5fTlMiXSkgPiBjb19mZXJyaXRpbiB8IGFzLm51bWVyaWMocm93WyJsYWJfZmVycml0aW5fYWRtaXMiXSkgPiBjb19mZXJyaXRpbiB8IGFzLm51bWVyaWMocm93WyJsYWJfZmVycml0aW5fcGVhayJdKSA+IGNvX2ZlcnJpdGluKQogICAgYWxidW1pbiA8LSBhcy5udW1lcmljKHJvd1sibGFiX2FsYnVtaW5fYWRtaXMiXSkgPCBjb19hbGJ1IHwgYXMubnVtZXJpYyhyb3dbImxhYl9hbGJ1bWluX2xvd2VzdCJdKSA8IGNvX2FsYnUgfCBhcy5udW1lcmljKHJvd1sibGFiX2FsYnVtaW5fTlMiXSkgPCBjb19hbGJ1CiAgICBQQ1QgPC0gYXMubnVtZXJpYyhyb3dbImxhYl9QQ1RfYWRtaXMiXSkgPiBjb19QQ1QgfCBhcy5udW1lcmljKHJvd1sibGFiX1BDVF9wZWFrIl0pID4gY29fUENUIHwgYXMubnVtZXJpYyhyb3dbImxhYl9QQ1RfTlMiXSkgPiBjb19QQ1QgCiAgICBMREggPC0gYXMubnVtZXJpYyhyb3dbImxhYl9MREgiXSkgPiBjb19MREgKICAgIElMNiA8LSBhcy5udW1lcmljKHJvd1sibGFiX0lMNiJdKSA+IGNvX0lMNgogICAgRVNSIDwtIGFzLm51bWVyaWMocm93WyJsYWJfRVNSIl0pID4gY29fRVNSCgogICAgY3JpdGVyaWE0IDwtIGFueShuZXV0cm9waGlsaWEsIGVsZXZhdGVkX0NSUCwgbHltcGhvcGVuaWEsIGZlcnJpdGluLCBhbGJ1bWluLCBQQ1QsIExESCwgSUw2LCBFU1IpCgogICAgIyBjcml0ZXJpYSA1OiBObyBvdGhlciBvYnZpb3VzIG1pY3JvYmlhbCBjYXVzZSBvZiBpbmZsYW1tYXRpb24KICAgIGNyaXRlcmlhNSA8LSBUUlVFCiAgICAKICAgICMgY3JpdGVyaWEgNjogQ09WSUQgcG9zPwogICAgUENSX3BvcyA8LSByb3dbImNvdmlkX1BDUl9wb3MiXSA9PSBUUlVFCiAgICBzdG9vbF9wb3MgPC0gcm93WyJjb3ZpZF9QQ1Jfc3Rvb2xfcG9zIl0gPT0gVFJVRQogICAgY2xvc2Vjb250YWN0IDwtIHJvd1siY292aWRfY2xvc2Vjb250YWN0Il0gPT0gVFJVRQogICAgSWdBIDwtIHJvd1siY292aWRfSWdBX3BvcyJdID09IFRSVUUKICAgIElnTSA8LSByb3dbImNvdmlkX0lnTV9wb3MiXSA9PSBUUlVFICAgIAogICAgSWdHIDwtIHJvd1siY292aWRfSWdHX3BvcyJdID09IFRSVUUgICAgCiAgICBhbnlfc2VybyA8LSByb3dbImNvdmlkX3Nlcm9fcG9zIl0gPT0gVFJVRQogICAgCiAgICBjcml0ZXJpYTYgPC0gYW55KFBDUl9wb3MsIHN0b29sX3BvcywgY2xvc2Vjb250YWN0LCBJZ0EsIElnTSwgSWdHLCBhbnlfc2VybykKICAgIAogICAgaWYgKE5BICVpbiUgYyhjcml0ZXJpYTEsIGNyaXRlcmlhMiwgY3JpdGVyaWEzLCBjcml0ZXJpYTQsIGNyaXRlcmlhNSwgY3JpdGVyaWE2KSl7CiAgICAgIGNyaXRlcmlhX2Z1bGZpbGxlZCA8LSBOQQogICAgfSBlbHNlIGlmIChGQUxTRSAlaW4lIGMoY3JpdGVyaWExLCBjcml0ZXJpYTIsIGNyaXRlcmlhMywgY3JpdGVyaWE0LCBjcml0ZXJpYTUsIGNyaXRlcmlhNikpewogICAgICBjcml0ZXJpYV9mdWxmaWxsZWQgPC0gRkFMU0UKICAgIH0gZWxzZSBpZiAoc3VtKGNyaXRlcmlhMSwgY3JpdGVyaWEyLCBjcml0ZXJpYTMsIGNyaXRlcmlhNCwgY3JpdGVyaWE1LCBjcml0ZXJpYTYsIG5hLnJtID0gVFJVRSkgPT0gNil7CiAgICAgIGNyaXRlcmlhX2Z1bGZpbGxlZCA8LSBUUlVFCiAgICB9IGVsc2UgewogICAgICBjcml0ZXJpYV9mdWxmaWxsZWQgPC0gRkFMU0UKICAgIH0KCiAgICByZXR1cm4oYyhwYXRfaWQsICJjcml0ZXJpYTFfYWdlIiA9IGNyaXRlcmlhMSwgImNyaXRlcmlhMl9mZXZlciIgPSBjcml0ZXJpYTIsICJjcml0ZXJpYTNfY2xpbmljYWwiID0gY3JpdGVyaWEzLCAiY3JpdGVyaWE0X2luZmxhbW0iID0gY3JpdGVyaWE0LCAiY3JpdGVyaWE1X25vQWx0IiA9IGNyaXRlcmlhNSwgImNyaXRlcmlhNl9yZWNlbnRFeHBvc3VyZSIgPSBjcml0ZXJpYTYsICJjcml0ZXJpYV9mdWxmaWxsZWQiID0gY3JpdGVyaWFfZnVsZmlsbGVkKSkKfSkKCgpXSE9fZnVsZmlsbGVkIDwtIFdIT19mdWxmaWxsZWQgJT4lIHQoKSAlPiUgYXNfdGliYmxlKCkKV0hPX2Z1bGZpbGxlZCA8LSB0eXBlX2NvbnZlcnQoV0hPX2Z1bGZpbGxlZCkKV0hPX2Z1bGZpbGxlZF9oZWF0bWFwIDwtIFdIT19mdWxmaWxsZWQKY29scyA8LSBzYXBwbHkoV0hPX2Z1bGZpbGxlZF9oZWF0bWFwLCBpcy5sb2dpY2FsKQpXSE9fZnVsZmlsbGVkX2hlYXRtYXBbLGNvbHNdIDwtIGxhcHBseShXSE9fZnVsZmlsbGVkX2hlYXRtYXBbLGNvbHNdLCBhcy5udW1lcmljKQpXSE9fZnVsZmlsbGVkX2hlYXRtYXBfbWVsdCA8LSBXSE9fZnVsZmlsbGVkX2hlYXRtYXAgJT4lIG1lbHQoKQpXSE9fZnVsZmlsbGVkX2hlYXRtYXBfbWVsdFtpcy5uYShXSE9fZnVsZmlsbGVkX2hlYXRtYXBfbWVsdCldIDwtIDIKCnNraW0oV0hPX2Z1bGZpbGxlZCkKCiNnZ3Bsb3QoV0hPX2Z1bGZpbGxlZF9oZWF0bWFwX21lbHQsIGFlcyh4ID0gdmFyaWFibGUsIHkgPSBhcy5jaGFyYWN0ZXIocGF0aWVudElEX2ludCksIGZpbGwgPSBhcy5mYWN0b3IodmFsdWUpKSkgKyBnZW9tX3RpbGUoKSArIHRoZW1lX2NsYXNzaWMoKSArIHRoZW1lKGF4aXMubGluZT1lbGVtZW50X2JsYW5rKCkpICsgbGFicyh5ID0gIlBhdGllbnQgSUQiLCB4ID0gImNyaXRlcmlhIiwgZmlsbCA9ICJjcml0ZXJpYSBtZXQiLCB0aXRsZSA9ICJPdmVydmlldyBvZiB3aGljaCBzaW5nbGUgY2FzZXMgZnVsZmlsbCBXSE8gTUlTLUMgY2FzZSBkZWZpbml0aW9uIikgKyAgc2NhbGVfZmlsbF9tYW51YWwobGFiZWxzID0gYygiTm8iLCAiWWVzIiwgIk1pc3NpbmciKSwgdmFsdWVzID0gYygicGluazIiLCAicm95YWxibHVlMyIsICJkYXJrZ3JleSIpKSArIHRoZW1lKGF4aXMudGV4dC54PWVsZW1lbnRfdGV4dChhbmdsZT05MCwgaGp1c3Q9MSkpCmBgYAoKIyMgUGVyLWNhc2Ugb3ZlcnZpZXcKYGBge3IsIGZpZy5oZWlnaHQgPSAxMCwgZmlnLndpZHRoPTd9ClBJTVNfVFNfZnVsZmlsbGVkX2hlYXRtYXBfbWVsdCRjcml0ZXJpYSA8LSAiUElNUy1UUyIKV0hPX2Z1bGZpbGxlZF9oZWF0bWFwX21lbHQkY3JpdGVyaWEgPC0gIldITyIKQ0RDX2Z1bGZpbGxlZF9oZWF0bWFwX21lbHQkY3JpdGVyaWEgPC0gIkNEQyIKCmZ1bGxfaGVhdG1hcCA8LSByYmluZChQSU1TX1RTX2Z1bGZpbGxlZF9oZWF0bWFwX21lbHQsIFdIT19mdWxmaWxsZWRfaGVhdG1hcF9tZWx0LCBDRENfZnVsZmlsbGVkX2hlYXRtYXBfbWVsdCkKCmdncGxvdChmdWxsX2hlYXRtYXAsIGFlcyh4ID0gdmFyaWFibGUsIHkgPSBhcy5jaGFyYWN0ZXIocGF0aWVudElEX2ludCksIGZpbGwgPSBhcy5mYWN0b3IodmFsdWUpKSkgKyBnZW9tX3RpbGUoKSArIHRoZW1lX2NsYXNzaWMoKSArIHRoZW1lKGF4aXMubGluZT1lbGVtZW50X2JsYW5rKCkpICsgbGFicyh5ID0gIlBhdGllbnQgSUQiLCB4ID0gImNyaXRlcmlhIiwgZmlsbCA9ICJjcml0ZXJpYSBtZXQiLCB0aXRsZSA9ICJPdmVydmlldyBvZiB3aGljaCBzaW5nbGUgY2FzZXMgZnVsZmlsbCBjYXNlIGRlZmluaXRpb25zIikgKyAgc2NhbGVfZmlsbF9tYW51YWwobGFiZWxzID0gYygiTm8iLCAiWWVzIiwgIk1pc3NpbmciKSwgdmFsdWVzID0gd2VzX3BhbGV0dGUoIlppc3NvdTEiKSkgKyB0aGVtZShheGlzLnRleHQueD1lbGVtZW50X3RleHQoYW5nbGU9OTAsIGhqdXN0PTEpKSArIGZhY2V0X3dyYXAofiBjcml0ZXJpYSwgc2NhbGVzID0gImZyZWVfeCIpCgoKYGBgCgoKIyMgU3VtbWFyeQpgYGB7cn0KY3JpdGVyaWFfc3VtbWFyeSA8LSBkYXRhLmZyYW1lKFBJTVNfVFNfZnVsZmlsbGVkICU+JSBzZWxlY3QoY3JpdGVyaWFfZnVsZmlsbGVkKSwgQ0RDX2Z1bGZpbGxlZCAlPiUgc2VsZWN0KGNyaXRlcmlhX2Z1bGZpbGxlZCksIFdIT19mdWxmaWxsZWQgJT4lIHNlbGVjdChjcml0ZXJpYV9mdWxmaWxsZWQpKQpjb2xuYW1lcyhjcml0ZXJpYV9zdW1tYXJ5KSA8LSBjKCJQSU1TLVRTIiwgIkNEQyIsICJXSE8iKQoKY29scyA8LSBzYXBwbHkoY3JpdGVyaWFfc3VtbWFyeSwgaXMubG9naWNhbCkKY3JpdGVyaWFfc3VtbWFyeVssY29sc10gPC0gbGFwcGx5KGNyaXRlcmlhX3N1bW1hcnlbLGNvbHNdLCBhcy5udW1lcmljKQoKY3JpdGVyaWFfc3VtbWFyeSA8LSBjcml0ZXJpYV9zdW1tYXJ5ICU+JSBtZWx0KCkgJT4lIAogICAgICAgICAgICAgICAgICAgICAgICAgIGdyb3VwX2J5KHZhcmlhYmxlKSAlPiUgCiAgICAgICAgICAgICAgICAgICAgICAgICAgc3VtbWFyaXNlKGZ1bGZpbGxlZCA9IHN1bSh2YWx1ZSA9PSAxLCBuYS5ybSA9IFRSVUUpLCBub3RfZnVsZmlsbGVkID0gc3VtKHZhbHVlID09IDAsIG5hLnJtID0gVFJVRSksIG5vdF9hc3Nlc3NhYmxlID0gc3VtKGlzLm5hKHZhbHVlKSkpCmNyaXRlcmlhX3N1bW1hcnkkc3VtIDwtIHJvd1N1bXMoY3JpdGVyaWFfc3VtbWFyeVssLTFdKQoKY3JpdGVyaWFfc3VtbWFyeV9tZWx0IDwtIGNyaXRlcmlhX3N1bW1hcnkgJT4lIG1lbHQoKQpjb2xuYW1lcyhjcml0ZXJpYV9zdW1tYXJ5X21lbHQpIDwtIGMoImNlbnRlciIsICJmdWxmaWxsZWQiLCAiY291bnQiKQoKZmlsbF9iYXIgPC0gZ2dwbG90KGNyaXRlcmlhX3N1bW1hcnlfbWVsdCAlPiUgZmlsdGVyKGZ1bGZpbGxlZCAhPSAnc3VtJyksIGFlcyh4ID0gY2VudGVyLCB5ID0gY291bnQsIGZpbGwgPSBmdWxmaWxsZWQpKSArIAogICAgICBnZW9tX2JhcihzdGF0ID0gImlkZW50aXR5IiwgcG9zaXRpb24gPSAiZmlsbCIpICsgdGhlbWVfYncoKSArIAogICAgICBsYWJzKHkgPSAicmF0aW8iLCB0aXRsZSA9ICJTaW5nbGUgY2FzZXMgbWVldGluZyB3aGljaCBjcml0ZXJpYSIsIHN1YnRpdGxlID0gcGFzdGUwKCJwZXJjZW50IG9mIHRvdGFsIChuID0gIiwgbWF4KGNyaXRlcmlhX3N1bW1hcnlfbWVsdCRjb3VudCkgLCIpIikpICsKICAgICAgICBzY2FsZV9maWxsX21hbnVhbCh2YWx1ZXMgPSB3ZXNfcGFsZXR0ZSgiUm95YWwxIilbYygxLDIsNCldKQoKZG9kZ2VfYmFyIDwtIGdncGxvdChjcml0ZXJpYV9zdW1tYXJ5X21lbHQgJT4lIGZpbHRlcihmdWxmaWxsZWQgIT0gJ3N1bScpLCBhZXMoeCA9IGNlbnRlciwgeSA9IGNvdW50LCBmaWxsID0gZnVsZmlsbGVkKSkgKyAKICAgICAgZ2VvbV9iYXIoc3RhdCA9ICJpZGVudGl0eSIsIHBvc2l0aW9uID0gImRvZGdlIikgKyB0aGVtZV9idygpICsgCiAgICAgIGxhYnMoeSA9ICJuIiwgdGl0bGUgPSAiU2luZ2xlIGNhc2VzIG1lZXRpbmcgd2hpY2ggY3JpdGVyaWEiLCBzdWJ0aXRsZSA9ICJhYnNvbHV0ZSB2YWx1ZXMiKSArCiAgICAgICAgc2NhbGVfZmlsbF9tYW51YWwodmFsdWVzID0gd2VzX3BhbGV0dGUoIlJveWFsMSIpW2MoMSwyLDQpXSkKCmdnYXJyYW5nZShkb2RnZV9iYXIsIGZpbGxfYmFyLCBsZWdlbmQgPSAiYm90dG9tIiwgY29tbW9uLmxlZ2VuZCA9IFRSVUUpCmBgYAoKIyBBc3NvY2lhdGlvbiBvZiBjYXNlIGRlZmluaXRpb24gd2l0aCBvdXRjb21lCmBgYHtyfQpXSE9fb3V0Y29tZSA8LSBXSE9fZnVsZmlsbGVkX2hlYXRtYXAgJT4lIHNlbGVjdChjb250YWlucygicGF0aWVudElEX2ludCIpIHwgY29udGFpbnMoImNyaXRlcmlhX2Z1bGZpbGxlZCIpKQpjb2xuYW1lcyhXSE9fb3V0Y29tZSkgPC0gYygicGF0aWVudElEX2ludCIsICJjYXNlZGVmX1dIT19mdWxmaWxsZWQiKQoKQ0RDX291dGNvbWUgPC0gQ0RDX2Z1bGZpbGxlZF9oZWF0bWFwICU+JSBzZWxlY3QoY29udGFpbnMoInBhdGllbnRJRF9pbnQiKSB8IGNvbnRhaW5zKCJjcml0ZXJpYV9mdWxmaWxsZWQiKSkKY29sbmFtZXMoQ0RDX291dGNvbWUpIDwtIGMoInBhdGllbnRJRF9pbnQiLCAiY2FzZWRlZl9DRENfZnVsZmlsbGVkIikKClBJTVNfVFNfb3V0Y29tZSA8LSBQSU1TX1RTX2Z1bGZpbGxlZF9oZWF0bWFwICU+JSBzZWxlY3QoY29udGFpbnMoInBhdGllbnRJRF9pbnQiKSB8IGNvbnRhaW5zKCJjcml0ZXJpYV9mdWxmaWxsZWQiKSkKY29sbmFtZXMoUElNU19UU19vdXRjb21lKSA8LSBjKCJwYXRpZW50SURfaW50IiwgImNhc2VkZWZfUElNU19UU19mdWxmaWxsZWQiKQoKYXNzb2Nfb3V0Y29tZSA8LSBtZXJnZShXSE9fb3V0Y29tZSwgQ0RDX291dGNvbWUsIGJ5ID0gInBhdGllbnRJRF9pbnQiKQphc3NvY19vdXRjb21lIDwtIG1lcmdlKGFzc29jX291dGNvbWUsIFBJTVNfVFNfb3V0Y29tZSkKCiNhc3NvY19vdXRjb21lIDwtIGFzc29jX291dGNvbWVbY29tcGxldGUuY2FzZXMoYXNzb2Nfb3V0Y29tZVsgLC0xXSksXQoKb3V0Y29tZV9wYXJhbXMgPC0gZGZfc2luZ2xlY2FzZXMgJT4lIHNlbGVjdChwYXRpZW50SURfaW50IHwgc3ltcF9jYXJkaW92YXNjX2NvcmRpbGF0IHwgc3ltcF9jYXJkaW92YXNjX2FuZXVyeXNtIHwgc3ltcF9jYXJkaW92YXNjX3Nob2NrIHwgb3V0Y29tZV9kZWF0aCB8IGNyaXRjYXJlX01WIHwgY3JpdGNhcmVfRUNNTykKCmFzc29jX291dGNvbWVfZnVsbCA8LSBtZXJnZShvdXRjb21lX3BhcmFtcywgYXNzb2Nfb3V0Y29tZSwgYnkgPSAicGF0aWVudElEX2ludCIsIGFsbCA9IFRSVUUpCgoKY29scyA8LSBzYXBwbHkoYXNzb2Nfb3V0Y29tZV9mdWxsLCBpcy5sb2dpY2FsKQphc3NvY19vdXRjb21lX2Z1bGxbLGNvbHNdIDwtIGxhcHBseShhc3NvY19vdXRjb21lX2Z1bGxbLGNvbHNdLCBhcy5udW1lcmljKQoKCm1ha2VVcHNldFIoYXNzb2Nfb3V0Y29tZV9mdWxsICU+JSBzZWxlY3QoLWNvbnRhaW5zKCJwYXRpZW50SUQiKSkpCmBgYAoKIyMgVW5mYXZvdXJhYmxlIGNvdXJzZQpBIG5ldyB2YXJpYWJsZSAndW5mYXZvdXJhYmxlIGNvdXJzZScgbWFkZSwgd2hpY2ggY29udGFpbnMgdGhlIGZvbGxvd2luZzoKCi0gc3ltcF9jYXJkaW92YXNjX2NvcmRpbGF0IAotIHN5bXBfY2FyZGlvdmFzY19hbmV1cnlzbQotIHN5bXBfY2FyZGlvdmFzY19zaG9jayAKLSBvdXRjb21lX2RlYXRoCi0gY3JpdGNhcmVfTVYgCi0gY3JpdGNhcmVfRUNNTwotIGNyaXRjYXJlX1JSVAotIGNyaXRjYXJlX2lub3Ryb3AKLSBhZG1pc19QSUNVX2FkbWlzCgpNaWxkIHByZXNlbnRhdGlvbiBtZWFucyBhbGwgb2YgdGhlIGFib3ZlIGFyZSBlaXRoZXIgMCBvciBOQS4gCgpDYXNlcyB3aXRoIG1pc3NpbmcgdmFsdWVzIGluIGNhc2UgZGVmaW50aW9ucyBhcmUgcmVtb3ZlZC4KCmBgYHtyfQphc3NvY19vdXRjb21lIDwtIG1lcmdlKFdIT19vdXRjb21lLCBDRENfb3V0Y29tZSwgYnkgPSAicGF0aWVudElEX2ludCIpCmFzc29jX291dGNvbWUgPC0gbWVyZ2UoYXNzb2Nfb3V0Y29tZSwgUElNU19UU19vdXRjb21lKQphc3NvY19vdXRjb21lIDwtIG1lcmdlKGFzc29jX291dGNvbWUsIFBJTVNfVFNfb3V0Y29tZSkKYXNzb2Nfb3V0Y29tZSA8LSBhc3NvY19vdXRjb21lW2NvbXBsZXRlLmNhc2VzKGFzc29jX291dGNvbWVbICwtMV0pLF0KCm91dGNvbWVfcGFyYW1zIDwtIGRmX3NpbmdsZWNhc2VzICU+JSBzZWxlY3QocGF0aWVudElEX2ludCB8IGNvbnRhaW5zKCJjcml0Y2FyZSIpICB8IGNvbnRhaW5zKCJhZG1pc19QSUNVX2FkbWlzIikgfCBjb250YWlucygib3V0Y29tZV9kZWF0aCIpICB8Y29udGFpbnMgKCJzeW1wX2NhcmRpb3Zhc2NfY29yZGlsYXQiKSB8IGNvbnRhaW5zICgic3ltcF9jYXJkaW92YXNjX2FuZXVyeXNtIikgIHxjb250YWlucygic3ltcF9jYXJkaW92YXNjX3Nob2NrIikpCgphc3NvY19vdXRjb21lX2Z1bGwgPC0gbWVyZ2Uob3V0Y29tZV9wYXJhbXMsIGFzc29jX291dGNvbWUsIGJ5ID0gInBhdGllbnRJRF9pbnQiKQoKY29scyA8LSBzYXBwbHkoYXNzb2Nfb3V0Y29tZV9mdWxsLCBpcy5sb2dpY2FsKQphc3NvY19vdXRjb21lX2Z1bGxbLGNvbHNdIDwtIGxhcHBseShhc3NvY19vdXRjb21lX2Z1bGxbLGNvbHNdLCBhcy5udW1lcmljKQoKYXNzb2Nfb3V0Y29tZV9mdWxsJHVuZmF2b3VyYWJsZV9jb3Vyc2UgPC0gaWZlbHNlKGFzc29jX291dGNvbWVfZnVsbCRzeW1wX2NhcmRpb3Zhc2NfY29yZGlsYXQgPT0gMSB8IGFzc29jX291dGNvbWVfZnVsbCRzeW1wX2NhcmRpb3Zhc2NfYW5ldXJ5c20gPT0gMSB8IGFzc29jX291dGNvbWVfZnVsbCRzeW1wX2NhcmRpb3Zhc2Nfc2hvY2sgPT0gMSB8IGFzc29jX291dGNvbWVfZnVsbCRvdXRjb21lX2RlYXRoID09IDEgfCBhc3NvY19vdXRjb21lX2Z1bGwkY3JpdGNhcmVfTVYgPT0gMSB8IGFzc29jX291dGNvbWVfZnVsbCRjcml0Y2FyZV9FQ01PID09IDEgfCBhc3NvY19vdXRjb21lX2Z1bGwkY3JpdGNhcmVfUlJUID09IDEgfCBhc3NvY19vdXRjb21lX2Z1bGwkYWRtaXNfUElDVV9hZG1pcyA9PSAxIHwgYXNzb2Nfb3V0Y29tZV9mdWxsJGNyaXRjYXJlX2lub3Ryb3AgPT0gMSAsIDEsIDApCgphc3NvY19vdXRjb21lX2Z1bGwkbWlsZF9wcmVzZW50YXRpb24gPC0gaWZlbHNlKChhc3NvY19vdXRjb21lX2Z1bGwkdW5mYXZvdXJhYmxlX2NvdXJzZSA9PSAwIHwgaXMubmEoYXNzb2Nfb3V0Y29tZV9mdWxsJHVuZmF2b3VyYWJsZV9jb3Vyc2UpKSwgMSwgMCkKCm1ha2VVcHNldFIoYXNzb2Nfb3V0Y29tZV9mdWxsICU+JSBzZWxlY3QoY29udGFpbnMoImNhc2VkZWYiKSB8IGNvbnRhaW5zKCJ1bmZhdm91cmFibGVfY291cnNlIikgKSkKCgptYWtlVXBzZXRSKGFzc29jX291dGNvbWVfZnVsbCAlPiUgc2VsZWN0KGNvbnRhaW5zKCJjYXNlZGVmIikgfCBjb250YWlucygidW5mYXZvdXJhYmxlX2NvdXJzZSIpICB8IGNvbnRhaW5zKCJtaWxkX3ByZXMiKSApKQoKI2RhdGF0YWJsZShhc3NvY19vdXRjb21lX2Z1bGwgJT4lIHNlbGVjdChjb250YWlucygicGF0aWVudCIpIHwgY29udGFpbnMoImNhc2VkZWYiKSB8IGNvbnRhaW5zKCJ1bmZhdm91cmFibGVfY291cnNlIikgfCBjb250YWlucygibWlsZF9wcmVzIikpKQoKYGBgCgojIyBQSUNVIGNhbmRpZGF0ZQpBIG5ldyB2YXJpYWJsZSAnUElDVSBjYW5kaWRhdGUnIG1hZGUsIHdoaWNoIGNvbnRhaW5zIHRoZSBmb2xsb3dpbmc6CgotIHN5bXBfY2FyZGlvdmFzY19zaG9jayAKLSBvdXRjb21lX2RlYXRoCi0gY3JpdGNhcmVfTVYgCi0gY3JpdGNhcmVfRUNNTwotIGNyaXRjYXJlX1JSVAotIGNyaXRjYXJlX2lub3Ryb3AKLSBhZG1pc19QSUNVX2FkbWlzCgpNaWxkIHByZXNlbnRhdGlvbiBtZWFucyBhbGwgb2YgdGhlIGFib3ZlIGFyZSBlaXRoZXIgMCBvciBOQS4gCgpDYXNlcyB3aXRoIG1pc3NpbmcgdmFsdWVzIGluIGNhc2UgZGVmaW50aW9ucyBhcmUgcmVtb3ZlZC4KCmBgYHtyfQphc3NvY19vdXRjb21lIDwtIG1lcmdlKFdIT19vdXRjb21lLCBDRENfb3V0Y29tZSwgYnkgPSAicGF0aWVudElEX2ludCIpCmFzc29jX291dGNvbWUgPC0gbWVyZ2UoYXNzb2Nfb3V0Y29tZSwgUElNU19UU19vdXRjb21lKQphc3NvY19vdXRjb21lIDwtIGFzc29jX291dGNvbWVbY29tcGxldGUuY2FzZXMoYXNzb2Nfb3V0Y29tZVsgLC0xXSksXQoKb3V0Y29tZV9wYXJhbXMgPC0gZGZfc2luZ2xlY2FzZXMgJT4lIHNlbGVjdChwYXRpZW50SURfaW50IHwgY29udGFpbnMoImNyaXRjYXJlIikgIHwgY29udGFpbnMoImFkbWlzX1BJQ1VfYWRtaXMiKSB8IGNvbnRhaW5zKCJvdXRjb21lX2RlYXRoIikgIHxjb250YWlucyAoInN5bXBfY2FyZGlvdmFzY19jb3JkaWxhdCIpIHwgY29udGFpbnMgKCJzeW1wX2NhcmRpb3Zhc2NfYW5ldXJ5c20iKSAgfGNvbnRhaW5zKCJzeW1wX2NhcmRpb3Zhc2Nfc2hvY2siKSkKCmFzc29jX291dGNvbWVfZnVsbCA8LSBtZXJnZShvdXRjb21lX3BhcmFtcywgYXNzb2Nfb3V0Y29tZSwgYnkgPSAicGF0aWVudElEX2ludCIpCgpjb2xzIDwtIHNhcHBseShhc3NvY19vdXRjb21lX2Z1bGwsIGlzLmxvZ2ljYWwpCmFzc29jX291dGNvbWVfZnVsbFssY29sc10gPC0gbGFwcGx5KGFzc29jX291dGNvbWVfZnVsbFssY29sc10sIGFzLm51bWVyaWMpCgphc3NvY19vdXRjb21lX2Z1bGwkUElDVV9jYW5kaWRhdGUgPC0gaWZlbHNlKCBhc3NvY19vdXRjb21lX2Z1bGwkc3ltcF9jYXJkaW92YXNjX3Nob2NrID09IDEgfCBhc3NvY19vdXRjb21lX2Z1bGwkb3V0Y29tZV9kZWF0aCA9PSAxIHwgYXNzb2Nfb3V0Y29tZV9mdWxsJGNyaXRjYXJlX01WID09IDEgfCBhc3NvY19vdXRjb21lX2Z1bGwkY3JpdGNhcmVfRUNNTyA9PSAxIHwgYXNzb2Nfb3V0Y29tZV9mdWxsJGNyaXRjYXJlX1JSVCA9PSAxIHwgYXNzb2Nfb3V0Y29tZV9mdWxsJGFkbWlzX1BJQ1VfYWRtaXMgPT0gMSB8IGFzc29jX291dGNvbWVfZnVsbCRjcml0Y2FyZV9pbm90cm9wID09IDEgLCAxLCAwKQoKYXNzb2Nfb3V0Y29tZV9mdWxsJG1pbGRfcHJlc2VudGF0aW9uIDwtIGlmZWxzZSgoYXNzb2Nfb3V0Y29tZV9mdWxsJFBJQ1VfY2FuZGlkYXRlID09IDAgfCBpcy5uYShhc3NvY19vdXRjb21lX2Z1bGwkUElDVV9jYW5kaWRhdGUpKSwgMSwgMCkKCm1ha2VVcHNldFIoYXNzb2Nfb3V0Y29tZV9mdWxsICU+JSBzZWxlY3QoY29udGFpbnMoImNhc2VkZWYiKSB8IGNvbnRhaW5zKCJQSUNVX2NhbmRpZGF0ZSIpICkpCgoKbWFrZVVwc2V0Uihhc3NvY19vdXRjb21lX2Z1bGwgJT4lIHNlbGVjdChjb250YWlucygiY2FzZWRlZiIpIHwgY29udGFpbnMoIlBJQ1VfY2FuZGlkYXRlIikgIHwgY29udGFpbnMoIm1pbGRfcHJlcyIpICkpCgojZGF0YXRhYmxlKGFzc29jX291dGNvbWVfZnVsbCAlPiUgc2VsZWN0KGNvbnRhaW5zKCJwYXRpZW50IikgfCBjb250YWlucygiY2FzZWRlZiIpIHwgY29udGFpbnMoIlBJQ1VfY2FuZGlkYXRlIikgfCBjb250YWlucygibWlsZF9wcmVzIikpKQoKYGBgCgoKIyBTZXNzaW9uSW5mbwpgYGB7cn0Kc2Vzc2lvbkluZm8oKQpgYGA=